Commit f2119c6e authored by Grigory Fedorov's avatar Grigory Fedorov

Code from next gen branch overadded.

parent 5d6ce742
......@@ -29,7 +29,6 @@ import java.util.concurrent.ThreadFactory;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.content.res.TypedArray;
import android.os.Build;
import android.os.Handler;
import com.xabber.android.service.XabberService;
......@@ -42,8 +41,6 @@ import com.xabber.androiddev.R;
*/
public class Application extends android.app.Application {
public static final int SDK_INT = Integer.valueOf(Build.VERSION.SDK);
private static Application instance;
public static Application getInstance() {
......@@ -254,8 +251,7 @@ public class Application extends android.app.Application {
* @return
*/
public boolean isContactsSupported() {
return SDK_INT >= 5
&& checkCallingOrSelfPermission("android.permission.READ_CONTACTS") == PackageManager.PERMISSION_GRANTED;
return checkCallingOrSelfPermission("android.permission.READ_CONTACTS") == PackageManager.PERMISSION_GRANTED;
}
@Override
......
......@@ -16,15 +16,11 @@ package com.xabber.android.data;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.jivesoftware.smack.Connection;
import org.xbill.DNS.Options;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.util.Log;
/**
......@@ -37,54 +33,12 @@ public class LogManager implements OnLoadListener {
private static final boolean log;
private static final boolean debugable;
private static Method _getApplicationInfo;
static {
initCompatibility();
debugable = (getApplicationInfo(Application.getInstance()).flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
debugable = (Application.getInstance().getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
log = debugable && SettingsManager.debugLog();
};
private static void initCompatibility() {
try {
_getApplicationInfo = Context.class.getMethod("getApplicationInfo",
new Class[] {});
} catch (NoSuchMethodException nsme) {
}
}
public static ApplicationInfo getApplicationInfo(Context context) {
ApplicationInfo applicationInfo;
if (_getApplicationInfo != null) {
try {
applicationInfo = (ApplicationInfo) _getApplicationInfo
.invoke(context);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
} else {
throw new RuntimeException(e);
}
} catch (IllegalAccessException ie) {
throw new RuntimeException(ie);
}
} else {
try {
applicationInfo = context.getPackageManager()
.getApplicationInfo(context.getPackageName(), 0);
} catch (NameNotFoundException e) {
Log.e("LogManager",
"I can`t find my package in the system. Debug will be disabled.");
applicationInfo = new ApplicationInfo();
applicationInfo.flags = 0;
}
}
return applicationInfo;
}
private final static LogManager instance;
static {
......
......@@ -27,6 +27,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import com.xabber.android.data.Application;
import com.xabber.android.data.OnLoadListener;
......@@ -479,9 +480,9 @@ public class AvatarManager implements OnLoadListener, OnLowMemoryListener,
}
private int getLauncherLargeIconSize() {
if (Application.SDK_INT < 9)
if (Build.VERSION.SDK_INT < 9)
return BaseShortcutHelper.getLauncherLargeIconSize();
else if (Application.SDK_INT < 11)
else if (Build.VERSION.SDK_INT < 11)
return GingerbreadShortcutHelper.getLauncherLargeIconSize();
else
return HoneycombShortcutHelper.getLauncherLargeIconSize();
......
......@@ -21,7 +21,7 @@ import com.xabber.android.data.account.AccountManager;
import com.xabber.android.data.entity.BaseEntity;
import com.xabber.android.data.notification.EntityNotificationItem;
import com.xabber.android.data.roster.RosterManager;
import com.xabber.android.ui.MUCEditor;
import com.xabber.android.ui.MUCInvite;
import com.xabber.androiddev.R;
/**
......@@ -57,8 +57,7 @@ public class RoomInvite extends BaseEntity implements EntityNotificationItem {
@Override
public Intent getIntent() {
return MUCEditor.createInviteIntent(Application.getInstance(), account,
user);
return MUCInvite.createIntent(Application.getInstance(), account, user);
}
@Override
......
......@@ -27,6 +27,7 @@ import android.content.Intent;
import android.database.Cursor;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Vibrator;
import android.widget.RemoteViews;
......
......@@ -20,7 +20,7 @@ import com.xabber.android.data.Application;
import com.xabber.android.data.account.AccountManager;
import com.xabber.android.data.entity.BaseEntity;
import com.xabber.android.data.notification.EntityNotificationItem;
import com.xabber.android.ui.ContactAdd;
import com.xabber.android.ui.ContactSubscription;
import com.xabber.androiddev.R;
public class SubscriptionRequest extends BaseEntity implements
......@@ -32,7 +32,7 @@ public class SubscriptionRequest extends BaseEntity implements
@Override
public Intent getIntent() {
return ContactAdd.createSubscriptionIntent(Application.getInstance(),
return ContactSubscription.createIntent(Application.getInstance(),
account, user);
}
......
......@@ -14,10 +14,6 @@
*/
package com.xabber.android.service;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Notification;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
......@@ -36,9 +32,6 @@ import com.xabber.android.data.notification.NotificationManager;
*/
public class XabberService extends Service {
private Method startForeground;
private Method stopForeground;
private static XabberService instance;
public static XabberService getInstance() {
......@@ -50,27 +43,17 @@ public class XabberService extends Service {
super.onCreate();
instance = this;
LogManager.i(this, "onCreate");
// Try to get methods supported in API Level 5+
try {
startForeground = getClass().getMethod("startForeground",
new Class[] { int.class, Notification.class });
stopForeground = getClass().getMethod("stopForeground",
new Class[] { boolean.class });
} catch (NoSuchMethodException e) {
startForeground = stopForeground = null;
}
changeForeground();
}
public void changeForeground() {
if (SettingsManager.eventsPersistent()
&& Application.getInstance().isInitialized())
startForegroundWrapper(NotificationManager.getInstance()
.getPersistentNotification());
startForeground(NotificationManager.PERSISTENT_NOTIFICATION_ID,
NotificationManager.getInstance()
.getPersistentNotification());
else
stopForegroundWrapper();
stopForeground(true);
}
@Override
......@@ -83,7 +66,7 @@ public class XabberService extends Service {
public void onDestroy() {
super.onDestroy();
LogManager.i(this, "onDestroy");
stopForegroundWrapper();
stopForeground(true);
Application.getInstance().onServiceDestroy();
}
......@@ -92,56 +75,6 @@ public class XabberService extends Service {
return null;
}
/**
* This is a wrapper around the new startForeground method, using the older
* APIs if it is not available.
*/
void startForegroundWrapper(Notification notification) {
if (startForeground != null) {
Object[] startForegroundArgs = new Object[] {
Integer.valueOf(NotificationManager.PERSISTENT_NOTIFICATION_ID),
notification };
try {
startForeground.invoke(this, startForegroundArgs);
} catch (InvocationTargetException e) {
// Should not happen.
LogManager.w(this, "Unable to invoke startForeground" + e);
} catch (IllegalAccessException e) {
// Should not happen.
LogManager.w(this, "Unable to invoke startForeground" + e);
}
} else {
setForeground(true);
try {
((android.app.NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE))
.notify(NotificationManager.PERSISTENT_NOTIFICATION_ID,
notification);
} catch (SecurityException e) {
}
}
}
/**
* This is a wrapper around the new stopForeground method, using the older
* APIs if it is not available.
*/
void stopForegroundWrapper() {
if (stopForeground != null) {
try {
stopForeground.invoke(this, new Object[] { Boolean.TRUE });
// We don't want to clear notification bar.
} catch (InvocationTargetException e) {
// Should not happen.
LogManager.w(this, "Unable to invoke stopForeground" + e);
} catch (IllegalAccessException e) {
// Should not happen.
LogManager.w(this, "Unable to invoke stopForeground" + e);
}
} else {
setForeground(false);
}
}
public static Intent createIntent(Context context) {
return new Intent(context, XabberService.class);
}
......
......@@ -28,7 +28,6 @@ import com.xabber.android.data.account.AccountManager;
import com.xabber.android.data.account.OnAccountChangedListener;
import com.xabber.android.ui.adapter.AccountListAdapter;
import com.xabber.android.ui.adapter.BaseListEditorAdapter;
import com.xabber.android.ui.adapter.UpdatableAdapter;
import com.xabber.android.ui.helper.BaseListEditor;
import com.xabber.androiddev.R;
......@@ -119,7 +118,7 @@ public class AccountList extends BaseListEditor<String> implements
@Override
public void onAccountsChanged(Collection<String> accounts) {
((UpdatableAdapter) getListAdapter()).onChange();
adapter.onChange();
}
@Override
......
......@@ -14,62 +14,28 @@
*/
package com.xabber.android.ui;
import java.io.File;
import java.util.Collection;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.ClipboardManager;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
import com.xabber.android.data.ActivityManager;
import com.xabber.android.data.Application;
import com.xabber.android.data.LogManager;
import com.xabber.android.data.NetworkException;
import com.xabber.android.data.SettingsManager;
import com.xabber.android.data.SettingsManager.ChatsHideKeyboard;
import com.xabber.android.data.SettingsManager.SecurityOtrMode;
import com.xabber.android.data.account.OnAccountChangedListener;
import com.xabber.android.data.entity.BaseEntity;
import com.xabber.android.data.extension.archive.MessageArchiveManager;
import com.xabber.android.data.extension.attention.AttentionManager;
import com.xabber.android.data.extension.cs.ChatStateManager;
import com.xabber.android.data.extension.muc.MUCManager;
import com.xabber.android.data.extension.muc.RoomChat;
import com.xabber.android.data.extension.muc.RoomState;
import com.xabber.android.data.extension.otr.OTRManager;
import com.xabber.android.data.extension.otr.SecurityLevel;
import com.xabber.android.data.intent.EntityIntentBuilder;
import com.xabber.android.data.message.AbstractChat;
import com.xabber.android.data.message.MessageItem;
import com.xabber.android.data.message.MessageManager;
import com.xabber.android.data.message.OnChatChangedListener;
import com.xabber.android.data.message.RegularChat;
import com.xabber.android.data.notification.NotificationManager;
import com.xabber.android.data.roster.OnContactChangedListener;
import com.xabber.android.ui.adapter.ChatViewerAdapter;
import com.xabber.android.ui.adapter.OnTextChangedListener;
import com.xabber.android.ui.dialog.ConfirmDialogListener;
import com.xabber.android.ui.dialog.DialogBuilder;
import com.xabber.android.ui.dialog.ExportChatDialogBuilder;
import com.xabber.android.ui.helper.ManagedActivity;
import com.xabber.android.ui.widget.PageSwitcher;
import com.xabber.android.ui.widget.PageSwitcher.OnSelectListener;
......@@ -84,64 +50,25 @@ import com.xabber.androiddev.R;
* @author alexander.ivanov
*
*/
public class ChatViewer extends ManagedActivity implements
View.OnClickListener, View.OnKeyListener, OnSelectListener,
public class ChatViewer extends ManagedActivity implements OnSelectListener,
OnChatChangedListener, OnContactChangedListener,
OnAccountChangedListener, OnEditorActionListener,
ConfirmDialogListener, OnTextChangedListener {
OnAccountChangedListener {
/**
* Attention request.
*/
private static final String ACTION_ATTENTION = "com.xabber.android.data.ATTENTION";
/**
* Minimum number of new messages to be requested from the server side
* archive.
*/
private static final int MINIMUM_MESSAGES_TO_LOAD = 10;
private static final String SAVED_ACCOUNT = "com.xabber.android.ui.ChatViewer.SAVED_ACCOUNT";
private static final String SAVED_USER = "com.xabber.android.ui.ChatViewer.SAVED_USER";
private static final String SAVED_EXIT_ON_SEND = "com.xabber.android.ui.ChatViewer.EXIT_ON_SEND";
private static final int OPTION_MENU_VIEW_CONTACT_ID = 0x02;
private static final int OPTION_MENU_CHAT_LIST_ID = 0x03;
private static final int OPTION_MENU_CLOSE_CHAT_ID = 0x04;
private static final int OPTION_MENU_SHOW_HISTORY_ID = 0x05;
private static final int OPTION_MENU_SETTINGS_ID = 0x08;
private static final int OPTION_MENU_CLEAR_HISTORY_ID = 0x09;
private static final int OPTION_MENU_CLEAR_MESSAGE_ID = 0x0a;
private static final int OPTION_MENU_EXPORT_CHAT_ID = 0x0c;
private static final int OPTION_MENU_CALL_ATTENTION_ID = 0x0d;
private static final int OPTION_MENU_LEAVE_ROOM_ID = 0x10;
private static final int OPTION_MENU_JOIN_ROOM_ID = 0x11;
private static final int OPTION_MENU_MUC_INVITE_ID = 0x12;
private static final int OPTION_MENU_EDIT_ROOM_ID = 0x13;
private static final int OPTION_MENU_OCCUPANT_LIST_ID = 0x14;
private static final int OPTION_MENU_START_OTR_ID = 0x20;
private static final int OPTION_MENU_END_OTR_ID = 0x21;
private static final int OPTION_MENU_VERIFY_FINGERPRINT_ID = 0x22;
private static final int OPTION_MENU_VERIFY_QUESTION_ID = 0x23;
private static final int OPTION_MENU_VERIFY_SECRET_ID = 0x24;
private static final int OPTION_MENU_REFRESH_OTR_ID = 0x25;
private static final int CONTEXT_MENU_QUOTE_ID = 0x100;
private static final int CONTEXT_MENU_REPEAT_ID = 0x101;
private static final int CONTEXT_MENU_COPY_ID = 0x102;
private static final int CONTEXT_MENU_REMOVE_ID = 0x103;
private static final int DIALOG_EXPORT_CHAT_ID = 0x200;
private ChatViewerAdapter chatViewerAdapter;
private PageSwitcher pageSwitcher;
private String actionWithAccount;
private String actionWithUser;
private View actionWithView;
private MessageItem actionWithMessage;
private boolean exitOnSend;
......@@ -169,15 +96,9 @@ public class ChatViewer extends ManagedActivity implements
actionWithAccount = null;
actionWithUser = null;
actionWithView = null;
actionWithMessage = null;
setContentView(R.layout.chat_viewer);
chatViewerAdapter = new ChatViewerAdapter(this, account, user);
chatViewerAdapter.setOnClickListener(this);
chatViewerAdapter.setOnKeyListener(this);
chatViewerAdapter.setOnEditorActionListener(this);
chatViewerAdapter.setOnCreateContextMenuListener(this);
chatViewerAdapter.setOnTextChangedListener(this);
pageSwitcher = (PageSwitcher) findViewById(R.id.switcher);
pageSwitcher.setAdapter(chatViewerAdapter);
pageSwitcher.setOnSelectListener(this);
......@@ -214,7 +135,7 @@ public class ChatViewer extends ManagedActivity implements
intent.removeExtra(Intent.EXTRA_TEXT);
exitOnSend = true;
if (actionWithView != null)
insertText(additional);
chatViewerAdapter.insertText(actionWithView, additional);
}
}
isVisible = true;
......@@ -270,316 +191,10 @@ public class ChatViewer extends ManagedActivity implements
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.clear();
AbstractChat abstractChat = MessageManager.getInstance().getChat(
actionWithAccount, actionWithUser);
if (abstractChat != null && abstractChat instanceof RoomChat) {
if (((RoomChat) abstractChat).getState() == RoomState.unavailable)
menu.add(0, OPTION_MENU_JOIN_ROOM_ID, 0,
getResources().getText(R.string.muc_join)).setIcon(
android.R.drawable.ic_menu_add);
else
menu.add(0, OPTION_MENU_MUC_INVITE_ID, 0,
getResources().getText(R.string.muc_invite)).setIcon(
android.R.drawable.ic_menu_add);
} else {
menu.add(0, OPTION_MENU_VIEW_CONTACT_ID, 0,
getResources().getText(R.string.contact_editor)).setIcon(
android.R.drawable.ic_menu_edit);
}
menu.add(0, OPTION_MENU_CHAT_LIST_ID, 0, getText(R.string.chat_list))
.setIcon(R.drawable.ic_menu_friendslist);
menu.add(0, OPTION_MENU_SETTINGS_ID, 0, getText(R.string.chat_settings))
.setIcon(android.R.drawable.ic_menu_preferences);
menu.add(0, OPTION_MENU_SHOW_HISTORY_ID, 0,
getText(R.string.show_history)).setIcon(
R.drawable.ic_menu_archive);
if (abstractChat != null
&& abstractChat instanceof RoomChat
&& ((RoomChat) abstractChat).getState() != RoomState.unavailable) {
if (((RoomChat) abstractChat).getState() == RoomState.error)
menu.add(0, OPTION_MENU_EDIT_ROOM_ID, 0,
getResources().getText(R.string.muc_edit)).setIcon(
android.R.drawable.ic_menu_edit);
else
menu.add(0, OPTION_MENU_LEAVE_ROOM_ID, 0,
getResources().getText(R.string.muc_leave)).setIcon(
android.R.drawable.ic_menu_close_clear_cancel);
} else {
menu.add(0, OPTION_MENU_CLOSE_CHAT_ID, 0,
getResources().getText(R.string.close_chat)).setIcon(
android.R.drawable.ic_menu_close_clear_cancel);
}
menu.add(0, OPTION_MENU_CLEAR_MESSAGE_ID, 0,
getResources().getText(R.string.clear_message)).setIcon(
R.drawable.ic_menu_stop);
menu.add(0, OPTION_MENU_CLEAR_HISTORY_ID, 0,
getText(R.string.clear_history));
menu.add(0, OPTION_MENU_EXPORT_CHAT_ID, 0,
getText(R.string.export_chat));
if (abstractChat != null && abstractChat instanceof RegularChat) {
menu.add(0, OPTION_MENU_CALL_ATTENTION_ID, 0,
getText(R.string.call_attention));
SecurityLevel securityLevel = OTRManager.getInstance()
.getSecurityLevel(abstractChat.getAccount(),
abstractChat.getUser());
SubMenu otrMenu = menu.addSubMenu(getText(R.string.otr_encryption));
otrMenu.setHeaderTitle(R.string.otr_encryption);
if (securityLevel == SecurityLevel.plain)
otrMenu.add(0, OPTION_MENU_START_OTR_ID, 0,
getText(R.string.otr_start))
.setEnabled(
SettingsManager.securityOtrMode() != SecurityOtrMode.disabled);
else
otrMenu.add(0, OPTION_MENU_REFRESH_OTR_ID, 0,
getText(R.string.otr_refresh));
otrMenu.add(0, OPTION_MENU_END_OTR_ID, 0, getText(R.string.otr_end))
.setEnabled(securityLevel != SecurityLevel.plain);
otrMenu.add(0, OPTION_MENU_VERIFY_FINGERPRINT_ID, 0,
getText(R.string.otr_verify_fingerprint)).setEnabled(
securityLevel != SecurityLevel.plain);
otrMenu.add(0, OPTION_MENU_VERIFY_QUESTION_ID, 0,
getText(R.string.otr_verify_question)).setEnabled(
securityLevel != SecurityLevel.plain);
otrMenu.add(0, OPTION_MENU_VERIFY_SECRET_ID, 0,
getText(R.string.otr_verify_secret)).setEnabled(
securityLevel != SecurityLevel.plain);
}
if (abstractChat != null && abstractChat instanceof RoomChat
&& ((RoomChat) abstractChat).getState() == RoomState.available)
menu.add(0, OPTION_MENU_OCCUPANT_LIST_ID, 0, getResources()
.getText(R.string.occupant_list));
chatViewerAdapter.onPrepareOptionsMenu(actionWithView, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case OPTION_MENU_VIEW_CONTACT_ID:
startActivity(ContactEditor.createIntent(this, actionWithAccount,
actionWithUser));
return true;
case OPTION_MENU_CHAT_LIST_ID:
startActivity(ChatList.createIntent(this));
return true;
case OPTION_MENU_CLOSE_CHAT_ID:
MessageManager.getInstance().closeChat(actionWithAccount,
actionWithUser);
NotificationManager.getInstance().removeMessageNotification(
actionWithAccount, actionWithUser);
close();
return true;
case OPTION_MENU_CLEAR_HISTORY_ID:
MessageManager.getInstance().clearHistory(actionWithAccount,
actionWithUser);
chatViewerAdapter.onChatChange(actionWithView, false);
return true;
case OPTION_MENU_SHOW_HISTORY_ID:
MessageManager.getInstance().requestToLoadLocalHistory(
actionWithAccount, actionWithUser);
MessageArchiveManager.getInstance().requestHistory(
actionWithAccount, actionWithUser,
MINIMUM_MESSAGES_TO_LOAD, 0);
chatViewerAdapter.onChange();
chatViewerAdapter.onChatChange(actionWithView, false);
return true;
case OPTION_MENU_SETTINGS_ID:
startActivity(ChatEditor.createIntent(this, actionWithAccount,
actionWithUser));
return true;
case OPTION_MENU_CLEAR_MESSAGE_ID:
((EditText) actionWithView.findViewById(R.id.chat_input))
.setText("");
return true;
case OPTION_MENU_EXPORT_CHAT_ID:
showDialog(DIALOG_EXPORT_CHAT_ID);
return true;
case OPTION_MENU_CALL_ATTENTION_ID:
try {
AttentionManager.getInstance().sendAttention(actionWithAccount,
actionWithUser);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
return true;
case OPTION_MENU_JOIN_ROOM_ID:
MUCManager.getInstance().joinRoom(actionWithAccount,
actionWithUser, true);
return true;
case OPTION_MENU_LEAVE_ROOM_ID:
MUCManager.getInstance().leaveRoom(actionWithAccount,
actionWithUser);
MessageManager.getInstance().closeChat(actionWithAccount,
actionWithUser);
NotificationManager.getInstance().removeMessageNotification(
actionWithAccount, actionWithUser);
close();
return true;
case OPTION_MENU_MUC_INVITE_ID:
startActivity(ContactList.createRoomInviteIntent(this,
actionWithAccount, actionWithUser));
return true;
case OPTION_MENU_EDIT_ROOM_ID:
startActivity(MUCEditor.createIntent(this, actionWithAccount,
actionWithUser));
return true;
case OPTION_MENU_OCCUPANT_LIST_ID:
startActivity(OccupantList.createIntent(this, actionWithAccount,
actionWithUser));
return true;
case OPTION_MENU_START_OTR_ID:
try {
OTRManager.getInstance().startSession(actionWithAccount,
actionWithUser);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
return true;
case OPTION_MENU_REFRESH_OTR_ID:
try {
OTRManager.getInstance().refreshSession(actionWithAccount,
actionWithUser);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
return true;
case OPTION_MENU_END_OTR_ID:
try {
OTRManager.getInstance().endSession(actionWithAccount,
actionWithUser);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
return true;
case OPTION_MENU_VERIFY_FINGERPRINT_ID:
startActivity(FingerprintViewer.createIntent(this,
actionWithAccount, actionWithUser));
return true;
case OPTION_MENU_VERIFY_QUESTION_ID:
startActivity(QuestionViewer.createIntent(this, actionWithAccount,
actionWithUser, true, false, null));
return true;
case OPTION_MENU_VERIFY_SECRET_ID:
startActivity(QuestionViewer.createIntent(this, actionWithAccount,
actionWithUser, false, false, null));
return true;
}
return false;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, view, menuInfo);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
pageSwitcher.stopMovement();
ListView listView = (ListView) actionWithView
.findViewById(android.R.id.list);
actionWithMessage = (MessageItem) listView.getAdapter().getItem(
info.position);
if (actionWithMessage != null && actionWithMessage.getAction() != null)
actionWithMessage = null; // Skip action message
if (actionWithMessage == null)
return;
if (actionWithMessage.isError()) {
menu.add(0, CONTEXT_MENU_REPEAT_ID, 0,
getResources().getText(R.string.message_repeat));
}
menu.add(0, CONTEXT_MENU_QUOTE_ID, 0,
getResources().getText(R.string.message_quote));
menu.add(0, CONTEXT_MENU_COPY_ID, 0,
getResources().getText(R.string.message_copy));
menu.add(0, CONTEXT_MENU_REMOVE_ID, 0,
getResources().getText(R.string.message_remove));
}
/**
* Insert additional text to the input.
*
* @param additional
*/
private void insertText(String additional) {
EditText editView = (EditText) actionWithView
.findViewById(R.id.chat_input);
String source = editView.getText().toString();
int selection = editView.getSelectionEnd();
if (selection == -1)
selection = source.length();
else if (selection > source.length())
selection = source.length();
String before = source.substring(0, selection);
String after = source.substring(selection);
if (before.length() > 0 && !before.endsWith("\n"))
additional = "\n" + additional;
editView.setText(before + additional + after);
editView.setSelection(selection + additional.length());
}
@Override
public boolean onContextItemSelected(MenuItem item) {
if (actionWithMessage == null)
return false;
super.onContextItemSelected(item);
switch (item.getItemId()) {
case CONTEXT_MENU_QUOTE_ID:
insertText("> " + actionWithMessage.getText() + "\n");
return true;
case CONTEXT_MENU_REPEAT_ID:
sendMessage(actionWithMessage.getText());
return true;
case CONTEXT_MENU_COPY_ID:
((ClipboardManager) getSystemService(CLIPBOARD_SERVICE))
.setText(actionWithMessage.getSpannable());
return true;
case CONTEXT_MENU_REMOVE_ID:
MessageManager.getInstance().removeMessage(actionWithMessage);
chatViewerAdapter.onChatChange(actionWithView, false);
return true;
}
return false;
}
@Override
protected Dialog onCreateDialog(int id) {
super.onCreateDialog(id);
switch (id) {
case DIALOG_EXPORT_CHAT_ID:
return new ExportChatDialogBuilder(this, DIALOG_EXPORT_CHAT_ID,
this, actionWithAccount, actionWithUser).create();
default:
return null;
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.chat_send:
sendMessage();
break;
case R.id.title:
ListView listView = (ListView) actionWithView
.findViewById(android.R.id.list);
int size = listView.getCount();
if (size > 0)
listView.setSelection(size - 1);
default:
break;
}
}
@Override
public boolean onKey(View view, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN
&& keyCode == KeyEvent.KEYCODE_ENTER
&& SettingsManager.chatsSendByEnter()) {
sendMessage();
return true;
}
return false;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
......@@ -590,7 +205,7 @@ public class ChatViewer extends ManagedActivity implements
return super.onKeyDown(keyCode, event);
}
private void close() {
void close() {
finish();
if (!Intent.ACTION_SEND.equals(getIntent().getAction())) {
ActivityManager.getInstance().clearStack(false);
......@@ -599,10 +214,9 @@ public class ChatViewer extends ManagedActivity implements
}
}
@Override
public void onTextChanged(EditText editText, CharSequence text) {
ChatStateManager.getInstance().onComposing(actionWithAccount,
actionWithUser, text);
void onSent() {
if (exitOnSend)
close();
}
@Override
......@@ -614,7 +228,6 @@ public class ChatViewer extends ManagedActivity implements
LogManager.i(this, "onSelect: " + actionWithAccount + ":"
+ actionWithUser);
actionWithView = pageSwitcher.getSelectedView();
actionWithMessage = null;
if (isVisible)
MessageManager.getInstance().setVisibleChat(actionWithAccount,
actionWithUser);
......@@ -634,48 +247,10 @@ public class ChatViewer extends ManagedActivity implements
actionWithAccount = null;
actionWithUser = null;
actionWithView = null;
actionWithMessage = null;
if (PageSwitcher.LOG)
LogManager.i(this, "onUnselect");
}
private void sendMessage() {
if (actionWithView == null)
return;
EditText editView = (EditText) actionWithView
.findViewById(R.id.chat_input);
String text = editView.getText().toString();
int start = 0;
int end = text.length();
while (start < end
&& (text.charAt(start) == ' ' || text.charAt(start) == '\n'))
start += 1;
while (start < end
&& (text.charAt(end - 1) == ' ' || text.charAt(end - 1) == '\n'))
end -= 1;
text = text.substring(start, end);
if ("".equals(text))
return;
chatViewerAdapter.setOnTextChangedListener(null);
editView.setText("");
chatViewerAdapter.setOnTextChangedListener(this);
sendMessage(text);
if (exitOnSend)
close();
if (SettingsManager.chatsHideKeyboard() == ChatsHideKeyboard.always
|| (getResources().getBoolean(R.bool.landscape) && SettingsManager
.chatsHideKeyboard() == ChatsHideKeyboard.landscape)) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editView.getWindowToken(), 0);
}
}
private void sendMessage(String text) {
MessageManager.getInstance().sendMessage(actionWithAccount,
actionWithUser, text);
chatViewerAdapter.onChatChange(actionWithView, false);
}
@Override
public void onChatChanged(final String account, final String user,
final boolean incoming) {
......@@ -732,75 +307,6 @@ public class ChatViewer extends ManagedActivity implements
}
}
@Override
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEND) {
sendMessage();
return true;
}
return false;
}
@Override
public void onAccept(DialogBuilder dialogBuilder) {
switch (dialogBuilder.getDialogId()) {
case DIALOG_EXPORT_CHAT_ID:
ExportChatDialogBuilder builder = (ExportChatDialogBuilder) dialogBuilder;
exportChat(builder);
}
}
private void exportChat(ExportChatDialogBuilder dialogBuilder) {
//TODO: retain AsyncTask via retained fragment
new ChatExportAsyncTask(dialogBuilder).execute();
}
private class ChatExportAsyncTask extends AsyncTask<Void, Void, File> {
private ExportChatDialogBuilder builder;
public ChatExportAsyncTask(ExportChatDialogBuilder builder) {
this.builder = builder;
}
@Override
protected File doInBackground(Void... params) {
File file = null;
try {
file = MessageManager.getInstance().exportChat(
actionWithAccount, actionWithUser, builder.getName());
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
return file;
}
@Override
public void onPostExecute(File result) {
if (result != null) {
if (builder.isSendChecked()) {
Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("text/plain");
Uri uri = Uri.fromFile(result);
intent.putExtra(android.content.Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(intent,
getString(R.string.export_chat)));
} else {
Toast.makeText(ChatViewer.this, R.string.export_chat_done,
Toast.LENGTH_LONG).show();
}
}
}
}
@Override
public void onDecline(DialogBuilder dialogBuilder) {
}
@Override
public void onCancel(DialogBuilder dialogBuilder) {
}
private boolean selectChat(String account, String user) {
for (int position = 0; position < chatViewerAdapter.getCount(); position++)
if (((BaseEntity) chatViewerAdapter.getItem(position)).equals(
......@@ -817,6 +323,14 @@ public class ChatViewer extends ManagedActivity implements
return false;
}
public int getChatCount() {
return chatViewerAdapter.getCount();
}
public int getChatPosition(String account, String user) {
return chatViewerAdapter.getPosition(account, user);
}
public static Intent createIntent(Context context, String account,
String user) {
return new EntityIntentBuilder(context, ChatViewer.class)
......
package com.xabber.android.ui;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentActivity;
import android.text.ClipboardManager;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.View.OnKeyListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import com.xabber.android.data.Application;
import com.xabber.android.data.LogManager;
import com.xabber.android.data.NetworkException;
import com.xabber.android.data.SettingsManager;
import com.xabber.android.data.SettingsManager.ChatsHideKeyboard;
import com.xabber.android.data.SettingsManager.SecurityOtrMode;
import com.xabber.android.data.extension.archive.MessageArchiveManager;
import com.xabber.android.data.extension.attention.AttentionManager;
import com.xabber.android.data.extension.cs.ChatStateManager;
import com.xabber.android.data.extension.muc.MUCManager;
import com.xabber.android.data.extension.muc.RoomChat;
import com.xabber.android.data.extension.muc.RoomState;
import com.xabber.android.data.extension.otr.OTRManager;
import com.xabber.android.data.extension.otr.SecurityLevel;
import com.xabber.android.data.message.AbstractChat;
import com.xabber.android.data.message.MessageItem;
import com.xabber.android.data.message.MessageManager;
import com.xabber.android.data.message.RegularChat;
import com.xabber.android.data.message.chat.ChatManager;
import com.xabber.android.data.notification.NotificationManager;
import com.xabber.android.data.roster.AbstractContact;
import com.xabber.android.data.roster.RosterManager;
import com.xabber.android.ui.adapter.ChatMessageAdapter;
import com.xabber.android.ui.dialog.ChatExportDialogFragment;
import com.xabber.android.ui.helper.AbstractAvatarInflaterHelper;
import com.xabber.android.ui.helper.ContactTitleInflater;
import com.xabber.android.ui.widget.PageSwitcher;
import com.xabber.androiddev.R;
public class ChatViewerFragment implements OnCreateContextMenuListener {
/**
* Minimum number of new messages to be requested from the server side
* archive.
*/
private static final int MINIMUM_MESSAGES_TO_LOAD = 10;
/**
* Delay before hide pages.
*/
private static final long PAGES_HIDDER_DELAY = 1000;
private AbstractAvatarInflaterHelper avatarInflaterHelper;
private boolean skipOnTextChanges;
private TextView pageView;
private View titleView;
private EditText inputView;
private ListView listView;
private ChatMessageAdapter chatMessageAdapter;
/**
* Whether pages are shown.
*/
private boolean pagesShown;
/**
* Animation used to hide pages.
*/
private Animation pagesHideAnimation;
/**
* Animation used for incoming message notification.
*/
private Animation shakeAnimation;
private Handler handler;
/**
* Runnable called to hide pages.
*/
private final Runnable pagesHideRunnable = new Runnable() {
@Override
public void run() {
handler.removeCallbacks(this);
pageView.startAnimation(pagesHideAnimation);
}
};
private final FragmentActivity activity;
private final View view;
public ChatViewerFragment(FragmentActivity activity) {
this.activity = activity;
onCreate(null);
view = onCreateView(activity.getLayoutInflater(), null, null);
}
private FragmentActivity getActivity() {
return activity;
}
private String getString(int resId, Object... formatArgs) {
return activity.getString(resId, formatArgs);
}
private void registerForContextMenu(View view) {
view.setOnCreateContextMenuListener(this);
}
public View getView() {
return view;
}
public void onCreate(Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
avatarInflaterHelper = AbstractAvatarInflaterHelper
.createAbstractContactInflaterHelper();
handler = new Handler();
pagesShown = false;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
shakeAnimation = AnimationUtils.loadAnimation(getActivity(),
R.anim.shake);
pagesHideAnimation = AnimationUtils.loadAnimation(getActivity(),
R.anim.chat_page_out);
pagesHideAnimation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
pageView.setVisibility(View.GONE);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
View view = inflater.inflate(R.layout.chat_viewer_item, container,
false);
chatMessageAdapter = new ChatMessageAdapter(getActivity());
pageView = (TextView) view.findViewById(R.id.chat_page);
titleView = view.findViewById(R.id.title);
inputView = (EditText) view.findViewById(R.id.chat_input);
listView = (ListView) view.findViewById(android.R.id.list);
listView.setAdapter(chatMessageAdapter);
view.findViewById(R.id.chat_send).setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
sendMessage();
}
});
titleView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int size = listView.getCount();
if (size > 0)
listView.setSelection(size - 1);
}
});
inputView.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View view, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN
&& keyCode == KeyEvent.KEYCODE_ENTER
&& SettingsManager.chatsSendByEnter()) {
sendMessage();
return true;
}
return false;
}
});
inputView.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView view, int actionId,
KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEND) {
sendMessage();
return true;
}
return false;
}
});
inputView.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable text) {
if (skipOnTextChanges)
return;
String account = chatMessageAdapter.getAccount();
String user = chatMessageAdapter.getUser();
ChatStateManager.getInstance().onComposing(account, user, text);
}
});
registerForContextMenu(listView);
return view;
}
public boolean onPrepareOptionsMenu(Menu menu) {
final String account = chatMessageAdapter.getAccount();
final String user = chatMessageAdapter.getUser();
AbstractChat abstractChat = MessageManager.getInstance().getChat(
account, user);
if (abstractChat != null && abstractChat instanceof RoomChat) {
if (((RoomChat) abstractChat).getState() == RoomState.unavailable)
menu.add(R.string.muc_join)
.setIcon(android.R.drawable.ic_menu_add)
.setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
MUCManager.getInstance().joinRoom(
account, user, true);
return true;
}
});
else
menu.add(R.string.muc_invite)
.setIcon(android.R.drawable.ic_menu_add)
.setIntent(
ContactList.createRoomInviteIntent(
getActivity(), account, user));
} else {
menu.add(R.string.contact_editor)
.setIcon(android.R.drawable.ic_menu_edit)
.setIntent(
ContactEditor.createIntent(getActivity(), account,
user));
}
menu.add(R.string.chat_list).setIcon(R.drawable.ic_menu_friendslist)
.setIntent(ChatList.createIntent(getActivity()));
menu.add(R.string.chat_settings)
.setIcon(android.R.drawable.ic_menu_preferences)
.setIntent(
ChatEditor.createIntent(getActivity(), account, user));
menu.add(R.string.show_history)
.setIcon(R.drawable.ic_menu_archive)
.setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
MessageManager.getInstance()
.requestToLoadLocalHistory(account,
user);
MessageArchiveManager.getInstance()
.requestHistory(account, user,
MINIMUM_MESSAGES_TO_LOAD, 0);
onChatChange(false);
return true;
}
});
if (abstractChat != null
&& abstractChat instanceof RoomChat
&& ((RoomChat) abstractChat).getState() != RoomState.unavailable) {
if (((RoomChat) abstractChat).getState() == RoomState.error)
menu.add(R.string.muc_edit)
.setIcon(android.R.drawable.ic_menu_edit)
.setIntent(
MUCEditor.createIntent(getActivity(), account,
user));
else
menu.add(R.string.muc_leave)
.setIcon(android.R.drawable.ic_menu_close_clear_cancel)
.setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
MUCManager.getInstance().leaveRoom(
account, user);
MessageManager.getInstance().closeChat(
account, user);
NotificationManager.getInstance()
.removeMessageNotification(
account, user);
((ChatViewer) getActivity()).close();
return true;
}
});
} else {
menu.add(R.string.close_chat)
.setIcon(android.R.drawable.ic_menu_close_clear_cancel)
.setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
MessageManager.getInstance().closeChat(
account, user);
NotificationManager.getInstance()
.removeMessageNotification(account,
user);
((ChatViewer) getActivity()).close();
return true;
}
});
}
menu.add(R.string.clear_message)
.setIcon(R.drawable.ic_menu_stop)
.setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
inputView.setText("");
return true;
}
});
menu.add(R.string.clear_history).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
MessageManager.getInstance()
.clearHistory(account, user);
onChatChange(false);
return false;
}
});
menu.add(R.string.export_chat).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
ChatExportDialogFragment
.newInstance(account, user)
.show(getActivity().getSupportFragmentManager(),
"CHAT_EXPORT");
return true;
}
});
if (abstractChat != null && abstractChat instanceof RegularChat) {
menu.add(R.string.call_attention).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
try {
AttentionManager.getInstance().sendAttention(
account, user);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
return true;
}
});
SecurityLevel securityLevel = OTRManager.getInstance()
.getSecurityLevel(abstractChat.getAccount(),
abstractChat.getUser());
SubMenu otrMenu = menu.addSubMenu(R.string.otr_encryption);
otrMenu.setHeaderTitle(R.string.otr_encryption);
if (securityLevel == SecurityLevel.plain)
otrMenu.add(R.string.otr_start)
.setEnabled(
SettingsManager.securityOtrMode() != SecurityOtrMode.disabled)
.setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
try {
OTRManager
.getInstance()
.startSession(account, user);
} catch (NetworkException e) {
Application.getInstance()
.onError(e);
}
return true;
}
});
else
otrMenu.add(R.string.otr_refresh).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
try {
OTRManager.getInstance().refreshSession(
account, user);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
return true;
}
});
otrMenu.add(R.string.otr_end)
.setEnabled(securityLevel != SecurityLevel.plain)
.setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
try {
OTRManager.getInstance().endSession(
account, user);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
return true;
}
});
otrMenu.add(R.string.otr_verify_fingerprint)
.setEnabled(securityLevel != SecurityLevel.plain)
.setIntent(
FingerprintViewer.createIntent(getActivity(),
account, user));
otrMenu.add(R.string.otr_verify_question)
.setEnabled(securityLevel != SecurityLevel.plain)
.setIntent(
QuestionViewer.createIntent(getActivity(), account,
user, true, false, null));
otrMenu.add(R.string.otr_verify_secret)
.setEnabled(securityLevel != SecurityLevel.plain)
.setIntent(
QuestionViewer.createIntent(getActivity(), account,
user, false, false, null));
}
if (abstractChat != null && abstractChat instanceof RoomChat
&& ((RoomChat) abstractChat).getState() == RoomState.available)
menu.add(R.string.occupant_list).setIntent(
OccupantList.createIntent(getActivity(), account, user));
return true;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view,
ContextMenuInfo menuInfo) {
// super.onCreateContextMenu(menu, view, menuInfo);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
final MessageItem message = (MessageItem) listView.getAdapter()
.getItem(info.position);
if (message != null && message.getAction() != null)
return;
if (message.isError()) {
menu.add(R.string.message_repeat).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
sendMessage(message.getText());
return true;
}
});
}
menu.add(R.string.message_quote).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
insertText("> " + message.getText() + "\n");
return true;
}
});
menu.add(R.string.message_copy).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
((ClipboardManager) getActivity().getSystemService(
Context.CLIPBOARD_SERVICE)).setText(message
.getSpannable());
return true;
}
});
menu.add(R.string.message_remove).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
MessageManager.getInstance().removeMessage(message);
onChatChange(false);
return true;
}
});
}
public void setChat(AbstractChat chat) {
final String account = chat.getAccount();
final String user = chat.getUser();
final AbstractContact abstractContact = RosterManager.getInstance()
.getBestContact(account, user);
if (chat.equals(chatMessageAdapter.getAccount(),
chatMessageAdapter.getUser())) {
chatMessageAdapter.updateInfo();
} else {
if (chatMessageAdapter.getAccount() != null
&& chatMessageAdapter.getUser() != null)
saveState();
if (PageSwitcher.LOG)
LogManager.i(this, "Load " + chatMessageAdapter.getUser()
+ " in " + chatMessageAdapter.getAccount());
skipOnTextChanges = true;
inputView.setText(ChatManager.getInstance().getTypedMessage(
account, user));
inputView.setSelection(
ChatManager.getInstance().getSelectionStart(account, user),
ChatManager.getInstance().getSelectionEnd(account, user));
skipOnTextChanges = false;
chatMessageAdapter.setChat(account, user);
listView.setAdapter(listView.getAdapter());
}
pageView.setText(getString(
R.string.chat_page,
((ChatViewer) getActivity()).getChatPosition(account, user) + 1,
((ChatViewer) getActivity()).getChatCount()));
ContactTitleInflater.updateTitle(titleView, getActivity(),
abstractContact);
avatarInflaterHelper.updateAvatar(
(ImageView) titleView.findViewById(R.id.avatar),
abstractContact);
SecurityLevel securityLevel = OTRManager.getInstance()
.getSecurityLevel(chat.getAccount(), chat.getUser());
SecurityOtrMode securityOtrMode = SettingsManager.securityOtrMode();
ImageView securityView = (ImageView) titleView
.findViewById(R.id.security);
if (securityLevel == SecurityLevel.plain
&& (securityOtrMode == SecurityOtrMode.disabled || securityOtrMode == SecurityOtrMode.manual)) {
securityView.setVisibility(View.GONE);
} else {
securityView.setVisibility(View.VISIBLE);
securityView.setImageLevel(securityLevel.getImageLevel());
}
}
public void saveState() {
if (PageSwitcher.LOG)
LogManager.i(this, "Save " + chatMessageAdapter.getUser() + " in "
+ chatMessageAdapter.getAccount());
ChatManager.getInstance().setTyped(chatMessageAdapter.getAccount(),
chatMessageAdapter.getUser(), inputView.getText().toString(),
inputView.getSelectionStart(), inputView.getSelectionEnd());
}
public void onChatChange(boolean incomingMessage) {
if (incomingMessage)
titleView.findViewById(R.id.name_holder).startAnimation(
shakeAnimation);
chatMessageAdapter.onChange();
}
/**
* Show pages.
*/
public void showPages() {
if (pagesShown)
return;
pagesShown = true;
handler.removeCallbacks(pagesHideRunnable);
pageView.clearAnimation();
pageView.setVisibility(View.VISIBLE);
}
/**
* Requests pages to be hiden in future.
*/
public void hidePages() {
if (!pagesShown)
return;
pagesShown = false;
handler.postDelayed(pagesHideRunnable, PAGES_HIDDER_DELAY);
}
/**
* Insert additional text to the input.
*
* @param additional
*/
public void insertText(String additional) {
String source = inputView.getText().toString();
int selection = inputView.getSelectionEnd();
if (selection == -1)
selection = source.length();
else if (selection > source.length())
selection = source.length();
String before = source.substring(0, selection);
String after = source.substring(selection);
if (before.length() > 0 && !before.endsWith("\n"))
additional = "\n" + additional;
inputView.setText(before + additional + after);
inputView.setSelection(selection + additional.length());
}
private void sendMessage() {
String text = inputView.getText().toString();
int start = 0;
int end = text.length();
while (start < end
&& (text.charAt(start) == ' ' || text.charAt(start) == '\n'))
start += 1;
while (start < end
&& (text.charAt(end - 1) == ' ' || text.charAt(end - 1) == '\n'))
end -= 1;
text = text.substring(start, end);
if ("".equals(text))
return;
skipOnTextChanges = true;
inputView.setText("");
skipOnTextChanges = false;
sendMessage(text);
((ChatViewer) getActivity()).onSent();
if (SettingsManager.chatsHideKeyboard() == ChatsHideKeyboard.always
|| (getActivity().getResources().getBoolean(R.bool.landscape) && SettingsManager
.chatsHideKeyboard() == ChatsHideKeyboard.landscape)) {
InputMethodManager imm = (InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(inputView.getWindowToken(), 0);
}
}
private void sendMessage(String text) {
final String account = chatMessageAdapter.getAccount();
final String user = chatMessageAdapter.getUser();
MessageManager.getInstance().sendMessage(account, user, text);
onChatChange(false);
}
}
......@@ -18,7 +18,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
......@@ -39,34 +38,19 @@ import com.xabber.android.data.intent.EntityIntentBuilder;
import com.xabber.android.data.message.MessageManager;
import com.xabber.android.data.roster.PresenceManager;
import com.xabber.android.data.roster.RosterManager;
import com.xabber.android.data.roster.SubscriptionRequest;
import com.xabber.android.ui.adapter.AccountChooseAdapter;
import com.xabber.android.ui.dialog.ConfirmDialogBuilder;
import com.xabber.android.ui.dialog.ConfirmDialogListener;
import com.xabber.android.ui.dialog.DialogBuilder;
import com.xabber.androiddev.R;
public class ContactAdd extends GroupListActivity implements
View.OnClickListener, ConfirmDialogListener, OnItemSelectedListener {
/**
* Action for subscription request to be show.
*
* Clear action on dialog dismiss.
*/
private static final String ACTION_SUBSCRIPTION_REQUEST = "com.xabber.android.data.SUBSCRIPTION_REQUEST";
View.OnClickListener, OnItemSelectedListener {
private static final String SAVED_ACCOUNT = "com.xabber.android.ui.ContactAdd.SAVED_ACCOUNT";
private static final String SAVED_USER = "com.xabber.android.ui.ContactAdd.SAVED_USER";
private static final String SAVED_NAME = "com.xabber.android.ui.ContactAdd.SAVED_NAME";
private static final int DIALOG_SUBSCRIPTION_REQUEST_ID = 0x20;
private String account;
private String user;
private SubscriptionRequest subscriptionRequest;
/**
* Views
*/
......@@ -125,17 +109,6 @@ public class ContactAdd extends GroupListActivity implements
userView.setText(user);
if (name != null)
nameView.setText(name);
if (ACTION_SUBSCRIPTION_REQUEST.equals(intent.getAction())) {
subscriptionRequest = PresenceManager.getInstance()
.getSubscriptionRequest(account, user);
if (subscriptionRequest == null) {
Application.getInstance().onError(R.string.ENTRY_IS_NOT_FOUND);
finish();
return;
}
} else {
subscriptionRequest = null;
}
}
@Override
......@@ -147,13 +120,6 @@ public class ContactAdd extends GroupListActivity implements
outState.putString(SAVED_NAME, nameView.getText().toString());
}
@Override
protected void onResume() {
super.onResume();
if (subscriptionRequest != null)
showDialog(DIALOG_SUBSCRIPTION_REQUEST_ID);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
......@@ -188,65 +154,6 @@ public class ContactAdd extends GroupListActivity implements
}
}
@Override
protected Dialog onCreateDialog(int id) {
Dialog dialog = super.onCreateDialog(id);
if (dialog != null)
return dialog;
switch (id) {
case DIALOG_SUBSCRIPTION_REQUEST_ID:
return new ConfirmDialogBuilder(this,
DIALOG_SUBSCRIPTION_REQUEST_ID, this).setMessage(
subscriptionRequest.getConfirmation()).create();
default:
return null;
}
}
@Override
public void onAccept(DialogBuilder dialogBuilder) {
super.onAccept(dialogBuilder);
switch (dialogBuilder.getDialogId()) {
case DIALOG_SUBSCRIPTION_REQUEST_ID:
try {
PresenceManager.getInstance().acceptSubscription(
subscriptionRequest.getAccount(),
subscriptionRequest.getUser());
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
getIntent().setAction(null);
break;
}
}
@Override
public void onDecline(DialogBuilder dialogBuilder) {
super.onDecline(dialogBuilder);
switch (dialogBuilder.getDialogId()) {
case DIALOG_SUBSCRIPTION_REQUEST_ID:
try {
PresenceManager.getInstance().discardSubscription(
subscriptionRequest.getAccount(),
subscriptionRequest.getUser());
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
finish();
break;
}
}
@Override
public void onCancel(DialogBuilder dialogBuilder) {
super.onCancel(dialogBuilder);
switch (dialogBuilder.getDialogId()) {
case DIALOG_SUBSCRIPTION_REQUEST_ID:
finish();
break;
}
}
@Override
Collection<String> getInitialGroups() {
String account = (String) accountView.getSelectedItem();
......@@ -283,21 +190,14 @@ public class ContactAdd extends GroupListActivity implements
return createIntent(context, null);
}
private static Intent createIntent(Context context, String account,
String user) {
return new EntityIntentBuilder(context, ContactAdd.class)
.setAccount(account).setUser(user).build();
}
public static Intent createIntent(Context context, String account) {
return createIntent(context, account, null);
}
public static Intent createSubscriptionIntent(Context context,
String account, String user) {
Intent intent = createIntent(context, account, user);
intent.setAction(ACTION_SUBSCRIPTION_REQUEST);
return intent;
public static Intent createIntent(Context context, String account,
String user) {
return new EntityIntentBuilder(context, ContactAdd.class)
.setAccount(account).setUser(user).build();
}
private static String getAccount(Intent intent) {
......
......@@ -30,23 +30,17 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v4.app.FragmentTransaction;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
......@@ -54,37 +48,27 @@ import com.xabber.android.data.ActivityManager;
import com.xabber.android.data.Application;
import com.xabber.android.data.NetworkException;
import com.xabber.android.data.SettingsManager;
import com.xabber.android.data.account.AccountItem;
import com.xabber.android.data.account.AccountManager;
import com.xabber.android.data.account.OnAccountChangedListener;
import com.xabber.android.data.account.StatusMode;
import com.xabber.android.data.connection.ConnectionManager;
import com.xabber.android.data.connection.ConnectionState;
import com.xabber.android.data.entity.BaseEntity;
import com.xabber.android.data.extension.avatar.AvatarManager;
import com.xabber.android.data.extension.muc.MUCManager;
import com.xabber.android.data.intent.EntityIntentBuilder;
import com.xabber.android.data.message.AbstractChat;
import com.xabber.android.data.message.MessageManager;
import com.xabber.android.data.message.OnChatChangedListener;
import com.xabber.android.data.notification.NotificationManager;
import com.xabber.android.data.roster.AbstractContact;
import com.xabber.android.data.roster.GroupManager;
import com.xabber.android.data.roster.OnContactChangedListener;
import com.xabber.android.data.roster.PresenceManager;
import com.xabber.android.data.roster.RosterContact;
import com.xabber.android.data.roster.RosterManager;
import com.xabber.android.data.roster.ShowOfflineMode;
import com.xabber.android.ui.adapter.AccountConfiguration;
import com.xabber.android.ui.ContactListFragment.OnContactClickListener;
import com.xabber.android.ui.adapter.AccountToggleAdapter;
import com.xabber.android.ui.adapter.ContactListAdapter;
import com.xabber.android.ui.adapter.GroupConfiguration;
import com.xabber.android.ui.dialog.AccountChooseDialogBuilder;
import com.xabber.android.ui.dialog.ConfirmDialogBuilder;
import com.xabber.android.ui.dialog.ConfirmDialogListener;
import com.xabber.android.ui.dialog.DialogBuilder;
import com.xabber.android.ui.dialog.GroupRenameDialogBuilder;
import com.xabber.android.ui.helper.ManagedListActivity;
import com.xabber.android.ui.dialog.AccountChooseDialogFragment;
import com.xabber.android.ui.dialog.AccountChooseDialogFragment.OnChoosedListener;
import com.xabber.android.ui.dialog.ContactIntegrationDialogFragment;
import com.xabber.android.ui.dialog.StartAtBootDialogFragment;
import com.xabber.android.ui.helper.ContextMenuHelper;
import com.xabber.android.ui.helper.ManagedActivity;
import com.xabber.androiddev.R;
import com.xabber.xmpp.address.Jid;
import com.xabber.xmpp.uri.XMPPUri;
......@@ -95,10 +79,9 @@ import com.xabber.xmpp.uri.XMPPUri;
* @author alexander.ivanov
*
*/
public class ContactList extends ManagedListActivity implements
OnContactChangedListener, OnAccountChangedListener,
OnChatChangedListener, View.OnClickListener, ConfirmDialogListener,
OnItemClickListener, OnLongClickListener {
public class ContactList extends ManagedActivity implements
OnAccountChangedListener, View.OnClickListener, OnLongClickListener,
OnChoosedListener, OnContactClickListener {
/**
* Select contact to be invited to the room was requested.
......@@ -108,12 +91,7 @@ public class ContactList extends ManagedListActivity implements
private static final long CLOSE_ACTIVITY_AFTER_DELAY = 300;
private static final String SAVED_ACTION = "com.xabber.android.ui.ContactList.SAVED_ACTION";
private static final String SAVED_ACTION_WITH_ACCOUNT = "com.xabber.android.ui.ContactList.SAVED_ACTION_WITH_ACCOUNT";
private static final String SAVED_ACTION_WITH_GROUP = "com.xabber.android.ui.ContactList.SAVED_ACTION_WITH_GROUP";
private static final String SAVED_ACTION_WITH_USER = "com.xabber.android.ui.ContactList.SAVED_ACTION_WITH_USER";
private static final String SAVED_SEND_TEXT = "com.xabber.android.ui.ContactList.SAVED_SEND_TEXT";
private static final String SAVED_OPEN_DIALOG_USER = "com.xabber.android.ui.ContactList.SAVED_OPEN_DIALOG_USER";
private static final String SAVED_OPEN_DIALOG_TEXT = "com.xabber.android.ui.ContactList.SAVED_OPEN_DIALOG_TEXT";
private static final int OPTION_MENU_ADD_CONTACT_ID = 0x02;
private static final int OPTION_MENU_STATUS_EDITOR_ID = 0x04;
......@@ -124,44 +102,9 @@ public class ContactList extends ManagedListActivity implements
private static final int OPTION_MENU_SEARCH_ID = 0x0A;
private static final int OPTION_MENU_CLOSE_CHATS_ID = 0x0B;
private static final int CONTEXT_MENU_VIEW_CHAT_ID = 0x12;
private static final int CONTEXT_MENU_EDIT_CONTACT_ID = 0x13;
private static final int CONTEXT_MENU_DELETE_CONTACT_ID = 0x14;
private static final int CONTEXT_MENU_CLOSE_CHAT_ID = 0x15;
private static final int CONTEXT_MENU_REQUEST_SUBSCRIPTION_ID = 0x16;
private static final int CONTEXT_MENU_ACCEPT_SUBSCRIPTION_ID = 0x17;
private static final int CONTEXT_MENU_DISCARD_SUBSCRIPTION_ID = 0x18;
private static final int CONTEXT_MENU_LEAVE_ROOM_ID = 0x19;
private static final int CONTEXT_MENU_JOIN_ROOM_ID = 0x1A;
private static final int CONTEXT_MENU_EDIT_ROOM_ID = 0x1B;
private static final int CONTEXT_MENU_VIEW_CONTACT_ID = 0x1C;
private static final int CONTEXT_MENU_GROUP_RENAME_ID = 0x31;
private static final int CONTEXT_MENU_GROUP_DELETE_ID = 0x32;
private static final int CONTEXT_MENU_ACCOUNT_EDITOR_ID = 0x33;
private static final int CONTEXT_MENU_ACCOUNT_STATUS_ID = 0x34;
private static final int CONTEXT_MENU_ACCOUNT_ADD_CONTACT_ID = 0x35;
private static final int CONTEXT_MENU_ACCOUNT_RECONNECT_ID = 0x39;
private static final int CONTEXT_MENU_ACCOUNT_VCARD_ID = 0x3A;
private static final int CONTEXT_MENU_SHOW_OFFLINE_GROUP_ID = 0x40;
private static final int CONTEXT_MENU_SHOW_OFFLINE_ALWAYS_ID = 0x41;
private static final int CONTEXT_MENU_SHOW_OFFLINE_NORMAL_ID = 0x42;
private static final int CONTEXT_MENU_SHOW_OFFLINE_NEVER_ID = 0x43;
private static final int DIALOG_DELETE_CONTACT_ID = 0x50;
private static final int DIALOG_DELETE_GROUP_ID = 0x51;
private static final int DIALOG_RENAME_GROUP_ID = 0x52;
private static final int DIALOG_START_AT_BOOT_ID = 0x53;
private static final int DIALOG_CONTACT_INTEGRATION_ID = 0x54;
private static final int DIALOG_OPEN_WITH_ACCOUNT_ID = 0x55;
private static final int DIALOG_CLOSE_APPLICATION_ID = 0x57;
/**
* Adapter for contact list.
*/
private ContactListAdapter contactListAdapter;
private static final String CONTACT_LIST_TAG = "CONTACT_LIST";
/**
* Adapter for account list.
......@@ -176,12 +119,7 @@ public class ContactList extends ManagedListActivity implements
/**
* Dialog related values.
*/
private String actionWithAccount;
private String actionWithGroup;
private String actionWithUser;
private String sendText;
private String openDialogUser;
private String openDialogText;
/**
* Title view.
......@@ -201,16 +139,14 @@ public class ContactList extends ManagedListActivity implements
return;
setContentView(R.layout.contact_list);
titleView = findViewById(android.R.id.title);
ListView listView = getListView();
listView.setOnItemClickListener(this);
listView.setItemsCanFocus(true);
FragmentTransaction fragmentTransaction = getSupportFragmentManager()
.beginTransaction();
fragmentTransaction.add(R.id.container, new ContactListFragment(),
CONTACT_LIST_TAG);
fragmentTransaction.commit();
registerForContextMenu(listView);
contactListAdapter = new ContactListAdapter(this);
setListAdapter(contactListAdapter);
accountToggleAdapter = new AccountToggleAdapter(this, this,
(LinearLayout) findViewById(R.id.account_list));
......@@ -231,29 +167,13 @@ public class ContactList extends ManagedListActivity implements
commonStatusMode.setOnClickListener(this);
commonStatusText.setOnClickListener(this);
titleView.setOnClickListener(this);
findViewById(R.id.button).setOnClickListener(this);
findViewById(R.id.back_button).setOnClickListener(this);
if (savedInstanceState != null) {
actionWithAccount = savedInstanceState
.getString(SAVED_ACTION_WITH_ACCOUNT);
actionWithGroup = savedInstanceState
.getString(SAVED_ACTION_WITH_GROUP);
actionWithUser = savedInstanceState
.getString(SAVED_ACTION_WITH_USER);
sendText = savedInstanceState.getString(SAVED_SEND_TEXT);
openDialogUser = savedInstanceState
.getString(SAVED_OPEN_DIALOG_USER);
openDialogText = savedInstanceState
.getString(SAVED_OPEN_DIALOG_TEXT);
action = savedInstanceState.getString(SAVED_ACTION);
} else {
actionWithAccount = null;
actionWithGroup = null;
actionWithUser = null;
sendText = null;
openDialogUser = null;
openDialogText = null;
action = getIntent().getAction();
}
getIntent().setAction(null);
......@@ -271,12 +191,7 @@ public class ContactList extends ManagedListActivity implements
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(SAVED_ACTION, action);
outState.putString(SAVED_ACTION_WITH_ACCOUNT, actionWithAccount);
outState.putString(SAVED_ACTION_WITH_GROUP, actionWithGroup);
outState.putString(SAVED_ACTION_WITH_USER, actionWithUser);
outState.putString(SAVED_SEND_TEXT, sendText);
outState.putString(SAVED_OPEN_DIALOG_USER, openDialogUser);
outState.putString(SAVED_OPEN_DIALOG_TEXT, openDialogText);
}
/**
......@@ -315,9 +230,8 @@ public class ContactList extends ManagedListActivity implements
text);
return;
}
openDialogUser = bareAddress;
openDialogText = text;
showDialog(DIALOG_OPEN_WITH_ACCOUNT_ID);
AccountChooseDialogFragment.newInstance(bareAddress, text).show(
getSupportFragmentManager(), "OPEN_WITH_ACCOUNT");
}
/**
......@@ -342,15 +256,8 @@ public class ContactList extends ManagedListActivity implements
super.onResume();
updateStatusBar();
rebuildAccountToggler();
Application.getInstance().addUIListener(OnAccountChangedListener.class,
this);
Application.getInstance().addUIListener(OnContactChangedListener.class,
this);
Application.getInstance().addUIListener(OnChatChangedListener.class,
this);
contactListAdapter.onChange();
if (ContactList.ACTION_ROOM_INVITE.equals(action)
|| Intent.ACTION_SEND.equals(action)
|| Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
......@@ -389,13 +296,15 @@ public class ContactList extends ManagedListActivity implements
if (SettingsManager.bootCount() > 2
&& !SettingsManager.connectionStartAtBoot()
&& !SettingsManager.startAtBootSuggested())
showDialog(DIALOG_START_AT_BOOT_ID);
StartAtBootDialogFragment.newInstance().show(
getSupportFragmentManager(), "START_AT_BOOT");
if (!SettingsManager.contactIntegrationSuggested()
&& Application.getInstance().isContactsSupported()) {
if (AccountManager.getInstance().getAllAccounts().isEmpty())
SettingsManager.setContactIntegrationSuggested();
else
showDialog(DIALOG_CONTACT_INTEGRATION_ID);
ContactIntegrationDialogFragment.newInstance().show(
getSupportFragmentManager(), "CONTACT_INTEGRATION");
}
}
}
......@@ -403,17 +312,8 @@ public class ContactList extends ManagedListActivity implements
@Override
protected void onPause() {
super.onPause();
unregisterListeners();
}
private void unregisterListeners() {
Application.getInstance().removeUIListener(
OnAccountChangedListener.class, this);
Application.getInstance().removeUIListener(
OnContactChangedListener.class, this);
Application.getInstance().removeUIListener(OnChatChangedListener.class,
this);
contactListAdapter.removeRefreshRequests();
}
@Override
......@@ -463,7 +363,7 @@ public class ContactList extends ManagedListActivity implements
case OPTION_MENU_EXIT_ID:
Application.getInstance().requestToClose();
showDialog(DIALOG_CLOSE_APPLICATION_ID);
unregisterListeners();
getContactListFragment().unregisterListeners();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
......@@ -483,330 +383,30 @@ public class ContactList extends ManagedListActivity implements
NotificationManager.getInstance().removeMessageNotification(
chat.getAccount(), chat.getUser());
}
contactListAdapter.onChange();
getContactListFragment().getAdapter().onChange();
return true;
}
return false;
}
private ContactListFragment getContactListFragment() {
return (ContactListFragment) getSupportFragmentManager()
.findFragmentByTag(CONTACT_LIST_TAG);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, view, menuInfo);
if (view == getListView()) {
final AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
BaseEntity baseEntity = (BaseEntity) getListView()
.getItemAtPosition(info.position);
if (baseEntity == null)
// Account toggler
return;
if (baseEntity instanceof AbstractContact) {
// Contact
actionWithAccount = baseEntity.getAccount();
actionWithGroup = null;
actionWithUser = baseEntity.getUser();
AbstractContact abstractContact = (AbstractContact) baseEntity;
menu.setHeaderTitle(abstractContact.getName());
menu.add(0, CONTEXT_MENU_VIEW_CHAT_ID, 0, getResources()
.getText(R.string.chat_viewer));
if (MUCManager.getInstance().hasRoom(actionWithAccount,
actionWithUser)) {
if (!MUCManager.getInstance().inUse(actionWithAccount,
actionWithUser))
menu.add(0, CONTEXT_MENU_EDIT_ROOM_ID, 0,
getResources().getText(R.string.muc_edit));
menu.add(0, CONTEXT_MENU_DELETE_CONTACT_ID, 0,
getResources().getText(R.string.muc_delete));
if (MUCManager.getInstance().isDisabled(actionWithAccount,
actionWithUser))
menu.add(0, CONTEXT_MENU_JOIN_ROOM_ID, 0,
getResources().getText(R.string.muc_join));
else
menu.add(0, CONTEXT_MENU_LEAVE_ROOM_ID, 0,
getResources().getText(R.string.muc_leave));
} else {
menu.add(0, CONTEXT_MENU_VIEW_CONTACT_ID, 0, getResources()
.getText(R.string.contact_viewer));
menu.add(0, CONTEXT_MENU_EDIT_CONTACT_ID, 0, getResources()
.getText(R.string.contact_editor));
menu.add(0, CONTEXT_MENU_DELETE_CONTACT_ID, 0,
getResources().getText(R.string.contact_delete));
if (MessageManager.getInstance().hasActiveChat(
actionWithAccount, actionWithUser))
menu.add(0, CONTEXT_MENU_CLOSE_CHAT_ID, 0,
getResources().getText(R.string.close_chat));
if (abstractContact.getStatusMode() == StatusMode.unsubscribed)
menu.add(0, CONTEXT_MENU_REQUEST_SUBSCRIPTION_ID, 0,
getText(R.string.request_subscription));
}
if (PresenceManager.getInstance().hasSubscriptionRequest(
actionWithAccount, actionWithUser)) {
menu.add(0, CONTEXT_MENU_ACCEPT_SUBSCRIPTION_ID, 0,
getResources()
.getText(R.string.accept_subscription));
menu.add(0, CONTEXT_MENU_DISCARD_SUBSCRIPTION_ID, 0,
getText(R.string.discard_subscription));
}
return;
} else if (baseEntity instanceof GroupConfiguration) {
// Group or account in contact list
actionWithAccount = baseEntity.getAccount();
actionWithGroup = baseEntity.getUser();
actionWithUser = null;
if (baseEntity instanceof AccountConfiguration) {
actionWithGroup = null;
} else {
// Group
menu.setHeaderTitle(GroupManager.getInstance()
.getGroupName(actionWithAccount, actionWithGroup));
if (actionWithGroup != GroupManager.ACTIVE_CHATS
&& actionWithGroup != GroupManager.IS_ROOM) {
menu.add(0, CONTEXT_MENU_GROUP_RENAME_ID, 0,
getText(R.string.group_rename));
if (actionWithGroup != GroupManager.NO_GROUP)
menu.add(0, CONTEXT_MENU_GROUP_DELETE_ID, 0,
getText(R.string.group_remove));
}
}
} else {
return;
}
} else {
// Account panel
actionWithAccount = (String) accountToggleAdapter
.getItemForView(view);
actionWithGroup = null;
actionWithUser = null;
}
// Group or account
if (actionWithGroup == null) {
// Account
menu.setHeaderTitle(AccountManager.getInstance().getVerboseName(
actionWithAccount));
AccountItem accountItem = AccountManager.getInstance().getAccount(
actionWithAccount);
ConnectionState state = accountItem.getState();
if (state == ConnectionState.waiting)
menu.add(0, CONTEXT_MENU_ACCOUNT_RECONNECT_ID, 0,
getText(R.string.account_reconnect));
menu.add(0, CONTEXT_MENU_ACCOUNT_STATUS_ID, 0,
getText(R.string.status_editor));
menu.add(0, CONTEXT_MENU_ACCOUNT_EDITOR_ID, 0,
getText(R.string.account_editor));
if (state.isConnected()) {
menu.add(0, CONTEXT_MENU_ACCOUNT_VCARD_ID, 0,
getText(R.string.contact_viewer));
menu.add(0, CONTEXT_MENU_ACCOUNT_ADD_CONTACT_ID, 0,
getText(R.string.contact_add));
}
}
if (actionWithGroup != null || SettingsManager.contactsShowAccounts()) {
SubMenu mapMode = menu.addSubMenu(getResources().getText(
R.string.show_offline_settings));
mapMode.setHeaderTitle(R.string.show_offline_settings);
MenuItem always = mapMode.add(CONTEXT_MENU_SHOW_OFFLINE_GROUP_ID,
CONTEXT_MENU_SHOW_OFFLINE_ALWAYS_ID, 0, getResources()
.getText(R.string.show_offline_always));
MenuItem normal = mapMode.add(CONTEXT_MENU_SHOW_OFFLINE_GROUP_ID,
CONTEXT_MENU_SHOW_OFFLINE_NORMAL_ID, 0, getResources()
.getText(R.string.show_offline_normal));
MenuItem never = mapMode.add(CONTEXT_MENU_SHOW_OFFLINE_GROUP_ID,
CONTEXT_MENU_SHOW_OFFLINE_NEVER_ID, 0, getResources()
.getText(R.string.show_offline_never));
mapMode.setGroupCheckable(CONTEXT_MENU_SHOW_OFFLINE_GROUP_ID, true,
true);
ShowOfflineMode showOfflineMode = GroupManager.getInstance()
.getShowOfflineMode(
actionWithAccount,
actionWithGroup == null ? GroupManager.IS_ACCOUNT
: actionWithGroup);
if (showOfflineMode == ShowOfflineMode.always)
always.setChecked(true);
else if (showOfflineMode == ShowOfflineMode.normal)
normal.setChecked(true);
else if (showOfflineMode == ShowOfflineMode.never)
never.setChecked(true);
else
throw new IllegalStateException();
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
super.onContextItemSelected(item);
switch (item.getItemId()) {
// Contact
case CONTEXT_MENU_VIEW_CHAT_ID:
MessageManager.getInstance().openChat(actionWithAccount,
actionWithUser);
startActivity(ChatViewer.createIntent(this, actionWithAccount,
actionWithUser));
return true;
case CONTEXT_MENU_VIEW_CONTACT_ID:
startActivity(ContactViewer.createIntent(this, actionWithAccount,
actionWithUser));
return true;
case CONTEXT_MENU_EDIT_CONTACT_ID:
startActivity(ContactEditor.createIntent(this, actionWithAccount,
actionWithUser));
return true;
case CONTEXT_MENU_DELETE_CONTACT_ID:
showDialog(DIALOG_DELETE_CONTACT_ID);
return true;
case CONTEXT_MENU_EDIT_ROOM_ID:
startActivity(MUCEditor.createIntent(this, actionWithAccount,
actionWithUser));
return true;
case CONTEXT_MENU_JOIN_ROOM_ID:
MUCManager.getInstance().joinRoom(actionWithAccount,
actionWithUser, true);
return true;
case CONTEXT_MENU_LEAVE_ROOM_ID:
MUCManager.getInstance().leaveRoom(actionWithAccount,
actionWithUser);
MessageManager.getInstance().closeChat(actionWithAccount,
actionWithUser);
NotificationManager.getInstance().removeMessageNotification(
actionWithAccount, actionWithUser);
contactListAdapter.onChange();
return true;
case CONTEXT_MENU_CLOSE_CHAT_ID:
MessageManager.getInstance().closeChat(actionWithAccount,
actionWithUser);
NotificationManager.getInstance().removeMessageNotification(
actionWithAccount, actionWithUser);
contactListAdapter.onChange();
return true;
case CONTEXT_MENU_REQUEST_SUBSCRIPTION_ID:
try {
PresenceManager.getInstance().requestSubscription(
actionWithAccount, actionWithUser);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
return true;
case CONTEXT_MENU_ACCEPT_SUBSCRIPTION_ID:
try {
PresenceManager.getInstance().acceptSubscription(
actionWithAccount, actionWithUser);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
startActivity(ContactEditor.createIntent(this, actionWithAccount,
actionWithUser));
return true;
case CONTEXT_MENU_DISCARD_SUBSCRIPTION_ID:
try {
PresenceManager.getInstance().discardSubscription(
actionWithAccount, actionWithUser);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
return true;
// Group
case CONTEXT_MENU_GROUP_RENAME_ID:
showDialog(DIALOG_RENAME_GROUP_ID);
return true;
case CONTEXT_MENU_GROUP_DELETE_ID:
showDialog(DIALOG_DELETE_GROUP_ID);
return true;
// Account
case CONTEXT_MENU_ACCOUNT_RECONNECT_ID:
if (AccountManager.getInstance().getAccount(actionWithAccount)
.updateConnection(true))
AccountManager.getInstance()
.onAccountChanged(actionWithAccount);
return true;
case CONTEXT_MENU_ACCOUNT_VCARD_ID:
String user = AccountManager.getInstance()
.getAccount(actionWithAccount).getRealJid();
if (user == null)
Application.getInstance().onError(R.string.NOT_CONNECTED);
else {
startActivity(ContactViewer.createIntent(this,
actionWithAccount, user));
}
return true;
case CONTEXT_MENU_ACCOUNT_EDITOR_ID:
startActivity(AccountEditor.createIntent(this, actionWithAccount));
return true;
case CONTEXT_MENU_ACCOUNT_STATUS_ID:
startActivity(StatusEditor.createIntent(this, actionWithAccount));
return true;
case CONTEXT_MENU_ACCOUNT_ADD_CONTACT_ID:
startActivity(ContactAdd.createIntent(this, actionWithAccount));
return true;
// Groups or account
case CONTEXT_MENU_SHOW_OFFLINE_ALWAYS_ID:
GroupManager.getInstance().setShowOfflineMode(
actionWithAccount,
actionWithGroup == null ? GroupManager.IS_ACCOUNT
: actionWithGroup, ShowOfflineMode.always);
contactListAdapter.onChange();
return true;
case CONTEXT_MENU_SHOW_OFFLINE_NORMAL_ID:
GroupManager.getInstance().setShowOfflineMode(
actionWithAccount,
actionWithGroup == null ? GroupManager.IS_ACCOUNT
: actionWithGroup, ShowOfflineMode.normal);
contactListAdapter.onChange();
return true;
case CONTEXT_MENU_SHOW_OFFLINE_NEVER_ID:
GroupManager.getInstance().setShowOfflineMode(
actionWithAccount,
actionWithGroup == null ? GroupManager.IS_ACCOUNT
: actionWithGroup, ShowOfflineMode.never);
contactListAdapter.onChange();
return true;
}
return false;
ContextMenuHelper.createAccountContextMenu(this,
getContactListFragment().getAdapter(),
accountToggleAdapter.getItemForView(view), menu);
}
@Override
protected Dialog onCreateDialog(int id) {
super.onCreateDialog(id);
switch (id) {
case DIALOG_DELETE_CONTACT_ID:
int resource;
if (MUCManager.getInstance().hasRoom(actionWithAccount,
actionWithUser))
resource = R.string.muc_delete_confirm;
else
resource = R.string.contact_delete_confirm;
return new ConfirmDialogBuilder(this, DIALOG_DELETE_CONTACT_ID,
this).setMessage(
getString(
resource,
RosterManager.getInstance().getName(
actionWithAccount, actionWithUser),
AccountManager.getInstance().getVerboseName(
actionWithAccount))).create();
case DIALOG_DELETE_GROUP_ID:
return new ConfirmDialogBuilder(this, DIALOG_DELETE_GROUP_ID, this)
.setMessage(
getString(R.string.group_remove_confirm,
actionWithGroup)).create();
case DIALOG_RENAME_GROUP_ID:
return new GroupRenameDialogBuilder(this, DIALOG_RENAME_GROUP_ID,
this, actionWithGroup == GroupManager.NO_GROUP ? ""
: actionWithGroup).create();
case DIALOG_START_AT_BOOT_ID:
return new ConfirmDialogBuilder(this, DIALOG_START_AT_BOOT_ID, this)
.setMessage(getString(R.string.start_at_boot_suggest))
.create();
case DIALOG_CONTACT_INTEGRATION_ID:
return new ConfirmDialogBuilder(this,
DIALOG_CONTACT_INTEGRATION_ID, this).setMessage(
getString(R.string.contact_integration_suggest)).create();
case DIALOG_OPEN_WITH_ACCOUNT_ID:
return new AccountChooseDialogBuilder(this,
DIALOG_OPEN_WITH_ACCOUNT_ID, this, openDialogUser).create();
case DIALOG_CLOSE_APPLICATION_ID:
ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog
......@@ -840,94 +440,28 @@ public class ContactList extends ManagedListActivity implements
case R.id.common_status_mode:
startActivity(StatusEditor.createIntent(this));
break;
case R.id.button: // Hint button
switch ((Integer) view.getTag()) {
case R.string.application_action_no_online:
SettingsManager.setContactsShowOffline(true);
contactListAdapter.onChange();
break;
case R.string.application_action_no_contacts:
startActivity(ContactAdd.createIntent(this));
break;
case R.string.application_action_waiting:
ConnectionManager.getInstance().updateConnections(true);
break;
case R.string.application_action_offline:
AccountManager.getInstance().setStatus(StatusMode.available,
null);
break;
case R.string.application_action_disabled:
startActivity(AccountList.createIntent(this));
break;
case R.string.application_action_empty:
startActivity(AccountAdd.createIntent(this));
break;
default:
break;
}
updateStatusBar();
break;
case R.id.back_button: // Xabber icon button
case R.id.common_status_text:
case android.R.id.title:
scrollUp();
getContactListFragment().scrollUp();
break;
default:
String account = (String) accountToggleAdapter.getItemForView(view);
String account = accountToggleAdapter.getItemForView(view);
if (account == null) // Check for tap on account in the title
break;
ListView listView = getListView();
if (!SettingsManager.contactsShowAccounts()) {
if (AccountManager.getInstance().getAccounts().size() < 2) {
scrollUp();
} else {
if (account.equals(AccountManager.getInstance()
.getSelectedAccount()))
SettingsManager.setContactsSelectedAccount("");
else
SettingsManager.setContactsSelectedAccount(account);
if (AccountManager.getInstance().getAccounts().size() < 2)
getContactListFragment().scrollUp();
else {
getContactListFragment().setSelectedAccount(account);
rebuildAccountToggler();
contactListAdapter.onChange();
stopMovement();
}
} else {
long count = listView.getCount();
for (int position = 0; position < (int) count; position++) {
BaseEntity baseEntity = (BaseEntity) listView
.getItemAtPosition(position);
if (baseEntity != null
&& baseEntity instanceof AccountConfiguration
&& baseEntity.getAccount().equals(account)) {
listView.setSelection(position);
stopMovement();
break;
}
}
}
} else
getContactListFragment().scrollTo(account);
break;
}
}
/**
* Stop fling scrolling.
*/
private void stopMovement() {
getListView().onTouchEvent(
MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL,
0, 0, 0));
}
/**
* Scroll to the top of contact list.
*/
private void scrollUp() {
ListView listView = getListView();
if (listView.getCount() > 0)
listView.setSelection(0);
stopMovement();
}
@Override
public boolean onLongClick(View view) {
switch (view.getId()) {
......@@ -939,161 +473,61 @@ public class ContactList extends ManagedListActivity implements
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Object object = parent.getAdapter().getItem(position);
if (object == null) {
// Account toggler
} else if (object instanceof AbstractContact) {
AbstractContact abstractContact = (AbstractContact) object;
if (ACTION_ROOM_INVITE.equals(action)) {
action = null;
Intent intent = getIntent();
String account = getRoomInviteAccount(intent);
String user = getRoomInviteUser(intent);
if (account != null && user != null)
try {
MUCManager.getInstance().invite(account, user,
abstractContact.getUser());
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
finish();
} else if (Intent.ACTION_SEND.equals(action)) {
action = null;
startActivity(ChatViewer.createSendIntent(this,
abstractContact.getAccount(),
abstractContact.getUser(), sendText));
finish();
} else if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
Intent intent = new Intent();
intent.putExtra(
Intent.EXTRA_SHORTCUT_INTENT,
ChatViewer.createClearTopIntent(this,
abstractContact.getAccount(),
abstractContact.getUser()));
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME,
abstractContact.getName());
Bitmap bitmap;
if (MUCManager.getInstance()
.hasRoom(abstractContact.getAccount(),
abstractContact.getUser()))
bitmap = AvatarManager.getInstance().getRoomBitmap(
abstractContact.getUser());
else
bitmap = AvatarManager.getInstance().getUserBitmap(
abstractContact.getUser());
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, AvatarManager
.getInstance().createShortcutBitmap(bitmap));
setResult(RESULT_OK, intent);
finish();
} else {
startActivity(ChatViewer
.createIntent(this, abstractContact.getAccount(),
abstractContact.getUser()));
}
} else if (object instanceof GroupConfiguration) {
GroupConfiguration groupConfiguration = (GroupConfiguration) object;
contactListAdapter.setExpanded(groupConfiguration.getAccount(),
groupConfiguration.getUser(),
!groupConfiguration.isExpanded());
}
}
@Override
public void onContactsChanged(Collection<BaseEntity> addresses) {
contactListAdapter.refreshRequest();
}
@Override
public void onAccountsChanged(Collection<String> accounts) {
accountToggleAdapter.onChange();
contactListAdapter.refreshRequest();
}
@Override
public void onChatChanged(String account, String user, boolean incoming) {
if (incoming)
contactListAdapter.refreshRequest();
}
@Override
public void onAccept(DialogBuilder dialogBuilder) {
switch (dialogBuilder.getDialogId()) {
case DIALOG_DELETE_CONTACT_ID:
if (MUCManager.getInstance().hasRoom(actionWithAccount,
actionWithUser)) {
MUCManager.getInstance().removeRoom(actionWithAccount,
actionWithUser);
MessageManager.getInstance().closeChat(actionWithAccount,
actionWithUser);
NotificationManager.getInstance().removeMessageNotification(
actionWithAccount, actionWithUser);
} else
public void onContactClick(AbstractContact abstractContact) {
if (ACTION_ROOM_INVITE.equals(action)) {
action = null;
Intent intent = getIntent();
String account = getRoomInviteAccount(intent);
String user = getRoomInviteUser(intent);
if (account != null && user != null)
try {
RosterManager.getInstance().removeContact(
actionWithAccount, actionWithUser);
MUCManager.getInstance().invite(account, user,
abstractContact.getUser());
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
break;
case DIALOG_DELETE_GROUP_ID:
try {
if (actionWithAccount == GroupManager.NO_ACCOUNT)
RosterManager.getInstance().removeGroup(actionWithGroup);
else
RosterManager.getInstance().removeGroup(actionWithAccount,
actionWithGroup);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
break;
case DIALOG_RENAME_GROUP_ID:
String name = ((GroupRenameDialogBuilder) dialogBuilder).getName();
String source = actionWithGroup == GroupManager.NO_GROUP ? null
: actionWithGroup;
try {
if (actionWithAccount == GroupManager.NO_ACCOUNT)
RosterManager.getInstance().renameGroup(source, name);
else
RosterManager.getInstance().renameGroup(actionWithAccount,
source, name);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
break;
case DIALOG_START_AT_BOOT_ID:
SettingsManager.setStartAtBootSuggested();
SettingsManager.setConnectionStartAtBoot(true);
break;
case DIALOG_CONTACT_INTEGRATION_ID:
SettingsManager.setContactIntegrationSuggested();
for (String account : AccountManager.getInstance().getAllAccounts())
AccountManager.getInstance().setSyncable(account, true);
break;
case DIALOG_OPEN_WITH_ACCOUNT_ID:
BaseEntity baseEntity = new BaseEntity(
((AccountChooseDialogBuilder) dialogBuilder).getSelected(),
openDialogUser);
openChat(baseEntity, openDialogText);
break;
finish();
} else if (Intent.ACTION_SEND.equals(action)) {
action = null;
startActivity(ChatViewer.createSendIntent(this,
abstractContact.getAccount(), abstractContact.getUser(),
sendText));
finish();
} else if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
Intent intent = new Intent();
intent.putExtra(
Intent.EXTRA_SHORTCUT_INTENT,
ChatViewer.createClearTopIntent(this,
abstractContact.getAccount(),
abstractContact.getUser()));
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME,
abstractContact.getName());
Bitmap bitmap;
if (MUCManager.getInstance().hasRoom(abstractContact.getAccount(),
abstractContact.getUser()))
bitmap = AvatarManager.getInstance().getRoomBitmap(
abstractContact.getUser());
else
bitmap = AvatarManager.getInstance().getUserBitmap(
abstractContact.getUser());
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, AvatarManager
.getInstance().createShortcutBitmap(bitmap));
setResult(RESULT_OK, intent);
finish();
} else {
startActivity(ChatViewer.createIntent(this,
abstractContact.getAccount(), abstractContact.getUser()));
}
}
@Override
public void onDecline(DialogBuilder dialogBuilder) {
switch (dialogBuilder.getDialogId()) {
case DIALOG_START_AT_BOOT_ID:
SettingsManager.setStartAtBootSuggested();
break;
case DIALOG_CONTACT_INTEGRATION_ID:
SettingsManager.setContactIntegrationSuggested();
break;
}
public void onAccountsChanged(Collection<String> accounts) {
accountToggleAdapter.onChange();
}
@Override
public void onCancel(DialogBuilder dialogBuilder) {
public void onChoosed(String account, String user, String text) {
openChat(new BaseEntity(account, user), text);
}
private void updateStatusBar() {
......
package com.xabber.android.ui;
import java.util.Collection;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.Fragment;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import com.xabber.android.data.Application;
import com.xabber.android.data.SettingsManager;
import com.xabber.android.data.account.AccountManager;
import com.xabber.android.data.account.CommonState;
import com.xabber.android.data.account.OnAccountChangedListener;
import com.xabber.android.data.account.StatusMode;
import com.xabber.android.data.connection.ConnectionManager;
import com.xabber.android.data.entity.BaseEntity;
import com.xabber.android.data.message.OnChatChangedListener;
import com.xabber.android.data.roster.AbstractContact;
import com.xabber.android.data.roster.OnContactChangedListener;
import com.xabber.android.ui.adapter.AccountConfiguration;
import com.xabber.android.ui.adapter.ContactListAdapter;
import com.xabber.android.ui.adapter.ContactListAdapter.OnContactListChangedListener;
import com.xabber.android.ui.adapter.ContactListState;
import com.xabber.android.ui.adapter.GroupConfiguration;
import com.xabber.android.ui.adapter.UpdatableAdapter;
import com.xabber.android.ui.helper.ContextMenuHelper;
import com.xabber.androiddev.R;
public class ContactListFragment extends Fragment implements
OnAccountChangedListener, OnContactChangedListener,
OnChatChangedListener, OnItemClickListener,
OnContactListChangedListener {
private ContactListAdapter adapter;
private ListView listView;
/**
* View with information shown on empty contact list.
*/
private View infoView;
/**
* Image view with connected icon.
*/
private View connectedView;
/**
* Image view with disconnected icon.
*/
private View disconnectedView;
/**
* View with help text.
*/
private TextView textView;
/**
* Button to apply help text.
*/
private Button buttonView;
/**
* Animation for disconnected view.
*/
private Animation animation;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.contact_list_fragment, container,
false);
listView = (ListView) view.findViewById(android.R.id.list);
listView.setOnItemClickListener(this);
listView.setItemsCanFocus(true);
registerForContextMenu(listView);
adapter = new ContactListAdapter(getActivity(), listView, this);
listView.setAdapter(adapter);
infoView = view.findViewById(R.id.info);
connectedView = infoView.findViewById(R.id.connected);
disconnectedView = infoView.findViewById(R.id.disconnected);
textView = (TextView) infoView.findViewById(R.id.text);
buttonView = (Button) infoView.findViewById(R.id.button);
animation = AnimationUtils.loadAnimation(getActivity(),
R.anim.connection);
return view;
}
@Override
public void onResume() {
super.onResume();
Application.getInstance().addUIListener(OnAccountChangedListener.class,
this);
Application.getInstance().addUIListener(OnContactChangedListener.class,
this);
Application.getInstance().addUIListener(OnChatChangedListener.class,
this);
adapter.onChange();
}
@Override
public void onPause() {
super.onPause();
unregisterListeners();
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view,
ContextMenuInfo menuInfo) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
BaseEntity baseEntity = (BaseEntity) listView
.getItemAtPosition(info.position);
if (baseEntity instanceof AbstractContact) {
ContextMenuHelper.createContactContextMenu(getActivity(), adapter,
(AbstractContact) baseEntity, menu);
} else if (baseEntity instanceof AccountConfiguration) {
ContextMenuHelper.createAccountContextMenu(getActivity(), adapter,
baseEntity.getAccount(), menu);
} else if (baseEntity instanceof GroupConfiguration) {
ContextMenuHelper.createGroupContextMenu(getActivity(), adapter,
baseEntity.getAccount(), baseEntity.getUser(), menu);
} else
throw new IllegalStateException();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Object object = parent.getAdapter().getItem(position);
if (object instanceof AbstractContact) {
((OnContactClickListener) getActivity())
.onContactClick((AbstractContact) object);
} else if (object instanceof GroupConfiguration) {
GroupConfiguration groupConfiguration = (GroupConfiguration) object;
adapter.setExpanded(groupConfiguration.getAccount(),
groupConfiguration.getUser(),
!groupConfiguration.isExpanded());
} else
throw new IllegalStateException();
}
@Override
public void onContactsChanged(Collection<BaseEntity> addresses) {
adapter.refreshRequest();
}
@Override
public void onAccountsChanged(Collection<String> accounts) {
adapter.refreshRequest();
}
@Override
public void onChatChanged(String account, String user, boolean incoming) {
if (incoming)
adapter.refreshRequest();
}
@Override
public void onContactListChanged(CommonState commonState,
boolean hasContacts, boolean hasVisibleContacts,
boolean isFilterEnabled) {
if (hasVisibleContacts) {
infoView.setVisibility(View.GONE);
disconnectedView.clearAnimation();
return;
}
infoView.setVisibility(View.VISIBLE);
final int text;
final int button;
final ContactListState state;
final OnClickListener listener;
if (isFilterEnabled) {
if (commonState == CommonState.online)
state = ContactListState.online;
else if (commonState == CommonState.roster
|| commonState == CommonState.connecting)
state = ContactListState.connecting;
else
state = ContactListState.offline;
text = R.string.application_state_no_online;
button = 0;
listener = null;
} else if (hasContacts) {
state = ContactListState.online;
text = R.string.application_state_no_online;
button = R.string.application_action_no_online;
listener = new OnClickListener() {
@Override
public void onClick(View view) {
SettingsManager.setContactsShowOffline(true);
adapter.onChange();
}
};
} else if (commonState == CommonState.online) {
state = ContactListState.online;
text = R.string.application_state_no_contacts;
button = R.string.application_action_no_contacts;
listener = new OnClickListener() {
@Override
public void onClick(View view) {
startActivity(ContactAdd.createIntent(getActivity()));
}
};
} else if (commonState == CommonState.roster) {
state = ContactListState.connecting;
text = R.string.application_state_roster;
button = 0;
listener = null;
} else if (commonState == CommonState.connecting) {
state = ContactListState.connecting;
text = R.string.application_state_connecting;
button = 0;
listener = null;
} else if (commonState == CommonState.waiting) {
state = ContactListState.offline;
text = R.string.application_state_waiting;
button = R.string.application_action_waiting;
listener = new OnClickListener() {
@Override
public void onClick(View view) {
ConnectionManager.getInstance().updateConnections(true);
}
};
} else if (commonState == CommonState.offline) {
state = ContactListState.offline;
text = R.string.application_state_offline;
button = R.string.application_action_offline;
listener = new OnClickListener() {
@Override
public void onClick(View view) {
AccountManager.getInstance().setStatus(
StatusMode.available, null);
}
};
} else if (commonState == CommonState.disabled) {
state = ContactListState.offline;
text = R.string.application_state_disabled;
button = R.string.application_action_disabled;
listener = new OnClickListener() {
@Override
public void onClick(View view) {
startActivity(AccountList.createIntent(getActivity()));
}
};
} else if (commonState == CommonState.empty) {
state = ContactListState.offline;
text = R.string.application_state_empty;
button = R.string.application_action_empty;
listener = new OnClickListener() {
@Override
public void onClick(View view) {
startActivity(AccountAdd.createIntent(getActivity()));
}
};
} else {
throw new IllegalStateException();
}
if (state == ContactListState.offline) {
connectedView.setVisibility(View.INVISIBLE);
disconnectedView.setVisibility(View.VISIBLE);
disconnectedView.clearAnimation();
} else if (state == ContactListState.connecting) {
connectedView.setVisibility(View.VISIBLE);
disconnectedView.setVisibility(View.VISIBLE);
if (disconnectedView.getAnimation() == null)
disconnectedView.startAnimation(animation);
} else if (state == ContactListState.online) {
connectedView.setVisibility(View.VISIBLE);
disconnectedView.setVisibility(View.INVISIBLE);
disconnectedView.clearAnimation();
}
textView.setText(text);
if (button == 0) {
buttonView.setVisibility(View.GONE);
} else {
buttonView.setVisibility(View.VISIBLE);
buttonView.setText(button);
}
buttonView.setOnClickListener(listener);
}
/**
* Force stop contact list updates before pause or application close.
*/
void unregisterListeners() {
Application.getInstance().removeUIListener(
OnAccountChangedListener.class, this);
Application.getInstance().removeUIListener(
OnContactChangedListener.class, this);
Application.getInstance().removeUIListener(OnChatChangedListener.class,
this);
adapter.removeRefreshRequests();
}
UpdatableAdapter getAdapter() {
return adapter;
}
/**
* Scroll contact list to specified account.
*
* @param account
*/
void scrollTo(String account) {
long count = listView.getCount();
for (int position = 0; position < (int) count; position++) {
BaseEntity baseEntity = (BaseEntity) listView
.getItemAtPosition(position);
if (baseEntity != null
&& baseEntity instanceof AccountConfiguration
&& baseEntity.getAccount().equals(account)) {
stopMovement();
listView.setSelection(position);
break;
}
}
}
/**
* Filter out contact list for selected account.
*
* @param account
*/
void setSelectedAccount(String account) {
if (account.equals(AccountManager.getInstance().getSelectedAccount()))
SettingsManager.setContactsSelectedAccount("");
else
SettingsManager.setContactsSelectedAccount(account);
stopMovement();
adapter.onChange();
}
/**
* Scroll to the top of contact list.
*/
void scrollUp() {
if (listView.getCount() > 0)
listView.setSelection(0);
stopMovement();
}
/**
* Stop fling scrolling.
*/
private void stopMovement() {
MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL, 0, 0, 0);
listView.onTouchEvent(event);
event.recycle();
}
public interface OnContactClickListener {
void onContactClick(AbstractContact contact);
}
}
/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber 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 this program. If not, see http://www.gnu.org/licenses/.
*/
package com.xabber.android.ui;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import com.xabber.android.data.Application;
import com.xabber.android.data.NetworkException;
import com.xabber.android.data.intent.EntityIntentBuilder;
import com.xabber.android.data.roster.PresenceManager;
import com.xabber.android.data.roster.SubscriptionRequest;
import com.xabber.android.ui.helper.ManagedDialog;
import com.xabber.androiddev.R;
public class ContactSubscription extends ManagedDialog {
private String account;
private String user;
private SubscriptionRequest subscriptionRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
account = getAccount(intent);
user = getUser(intent);
subscriptionRequest = PresenceManager.getInstance()
.getSubscriptionRequest(account, user);
if (subscriptionRequest == null) {
Application.getInstance().onError(R.string.ENTRY_IS_NOT_FOUND);
finish();
return;
}
setDialogMessage(subscriptionRequest.getConfirmation());
setDialogTitle(R.string.subscription_request_message);
findViewById(android.R.id.button3).setVisibility(View.GONE);
}
@Override
public void onAccept() {
super.onAccept();
try {
PresenceManager.getInstance().acceptSubscription(
subscriptionRequest.getAccount(),
subscriptionRequest.getUser());
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
startActivity(ContactAdd.createIntent(this, account, user));
finish();
}
@Override
public void onDecline() {
super.onDecline();
try {
PresenceManager.getInstance().discardSubscription(
subscriptionRequest.getAccount(),
subscriptionRequest.getUser());
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
finish();
}
public static Intent createIntent(Context context, String account,
String user) {
return new EntityIntentBuilder(context, ContactSubscription.class)
.setAccount(account).setUser(user).build();
}
private static String getAccount(Intent intent) {
return EntityIntentBuilder.getAccount(intent);
}
private static String getUser(Intent intent) {
return EntityIntentBuilder.getUser(intent);
}
}
......@@ -18,7 +18,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import android.app.Dialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
......@@ -30,9 +29,8 @@ import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.xabber.android.ui.dialog.ConfirmDialogListener;
import com.xabber.android.ui.dialog.DialogBuilder;
import com.xabber.android.ui.dialog.GroupAddDialogBuilder;
import com.xabber.android.ui.dialog.GroupAddDialogFragment;
import com.xabber.android.ui.dialog.GroupAddDialogFragment.OnGroupAddConfirmed;
import com.xabber.android.ui.helper.ManagedListActivity;
import com.xabber.androiddev.R;
......@@ -43,15 +41,13 @@ import com.xabber.androiddev.R;
*
*/
public abstract class GroupListActivity extends ManagedListActivity implements
ConfirmDialogListener, OnItemClickListener {
OnItemClickListener, OnGroupAddConfirmed {
private static final String SAVED_GROUPS = "com.xabber.android.ui.ContactList.SAVED_GROUPS";
private static final String SAVED_SELECTED = "com.xabber.android.ui.ContactList.SAVED_SELECTED";
static final int OPTION_MENU_ADD_GROUP_ID = 1;
static final int DIALOG_ADD_GROUP_ID = 0x10;
private ArrayAdapter<String> arrayAdapter;
private ListView listView;
......@@ -148,29 +144,22 @@ public abstract class GroupListActivity extends ManagedListActivity implements
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case OPTION_MENU_ADD_GROUP_ID:
showDialog(DIALOG_ADD_GROUP_ID);
showGroupAddDialog();
return true;
}
return false;
}
@Override
protected Dialog onCreateDialog(int id) {
super.onCreateDialog(id);
switch (id) {
case DIALOG_ADD_GROUP_ID:
return new GroupAddDialogBuilder(this, DIALOG_ADD_GROUP_ID, this,
getGroups()).create();
default:
return null;
}
private void showGroupAddDialog() {
GroupAddDialogFragment.newInstance(getGroups()).show(
getSupportFragmentManager(), "GROUP-ADD");
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
if (listView.getItemAtPosition(position) == null) // Footer
showDialog(DIALOG_ADD_GROUP_ID);
showGroupAddDialog();
}
/**
......@@ -192,24 +181,12 @@ public abstract class GroupListActivity extends ManagedListActivity implements
}
@Override
public void onAccept(DialogBuilder dialog) {
switch (dialog.getDialogId()) {
case DIALOG_ADD_GROUP_ID:
String group = ((GroupAddDialogBuilder) dialog).getName();
ArrayList<String> groups = getGroups();
groups.add(group);
ArrayList<String> selected = getSelected();
selected.add(group);
setGroups(groups, selected);
}
}
@Override
public void onDecline(DialogBuilder dialog) {
}
@Override
public void onCancel(DialogBuilder dialog) {
public void onGroupAddConfirmed(String group) {
ArrayList<String> groups = getGroups();
groups.add(group);
ArrayList<String> selected = getSelected();
selected.add(group);
setGroups(groups, selected);
}
}
......@@ -18,7 +18,6 @@ import java.util.Collection;
import org.jivesoftware.smack.util.StringUtils;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
......@@ -31,7 +30,6 @@ import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
import com.xabber.android.data.Application;
import com.xabber.android.data.account.AccountManager;
import com.xabber.android.data.extension.muc.MUCManager;
import com.xabber.android.data.extension.muc.RoomInvite;
......@@ -40,27 +38,15 @@ import com.xabber.android.data.intent.EntityIntentBuilder;
import com.xabber.android.data.message.MessageManager;
import com.xabber.android.data.notification.NotificationManager;
import com.xabber.android.ui.adapter.AccountChooseAdapter;
import com.xabber.android.ui.dialog.ConfirmDialogBuilder;
import com.xabber.android.ui.dialog.ConfirmDialogListener;
import com.xabber.android.ui.dialog.DialogBuilder;
import com.xabber.android.ui.helper.ManagedActivity;
import com.xabber.androiddev.R;
public class MUCEditor extends ManagedActivity implements View.OnClickListener,
OnItemSelectedListener, ConfirmDialogListener {
/**
* Action for MUC invitation to be show.
*
* Clear action on dialog dismiss.
*/
private static final String ACTION_MUC_INVITE = "com.xabber.android.data.MUC_INVITE";
OnItemSelectedListener {
private static final String SAVED_ACCOUNT = "com.xabber.android.ui.MUCEditor.SAVED_ACCOUNT";
private static final String SAVED_ROOM = "com.xabber.android.ui.MUCEditor.SAVED_ROOM";
private static final int DIALOG_MUC_INVITE_ID = 100;
private String account;
private String room;
......@@ -69,11 +55,6 @@ public class MUCEditor extends ManagedActivity implements View.OnClickListener,
*/
private int selectedAccount;
/**
* Invite intent.
*/
private RoomInvite roomInvite;
/**
* Views.
*/
......@@ -117,8 +98,15 @@ public class MUCEditor extends ManagedActivity implements View.OnClickListener,
.removeAuthorizationError(account, room);
nickView.setText(MUCManager.getInstance().getNickname(account,
room));
passwordView.setText(MUCManager.getInstance().getPassword(
account, room));
String password;
RoomInvite roomInvite = MUCManager.getInstance().getInvite(
account, room);
if (roomInvite != null)
password = roomInvite.getPassword();
else
password = MUCManager.getInstance().getPassword(account,
room);
passwordView.setText(password);
}
}
if (account == null) {
......@@ -137,17 +125,6 @@ public class MUCEditor extends ManagedActivity implements View.OnClickListener,
if ("".equals(nickView.getText().toString()))
nickView.setText(getNickname(((String) accountView
.getSelectedItem())));
if (ACTION_MUC_INVITE.equals(intent.getAction())) {
roomInvite = MUCManager.getInstance().getInvite(account, room);
if (roomInvite == null) {
Application.getInstance().onError(R.string.ENTRY_IS_NOT_FOUND);
finish();
return;
}
passwordView.setText(roomInvite.getPassword());
} else {
roomInvite = null;
}
}
@Override
......@@ -162,8 +139,6 @@ public class MUCEditor extends ManagedActivity implements View.OnClickListener,
protected void onResume() {
super.onResume();
selectedAccount = accountView.getSelectedItemPosition();
if (roomInvite != null)
showDialog(DIALOG_MUC_INVITE_ID);
}
@Override
......@@ -199,14 +174,15 @@ public class MUCEditor extends ManagedActivity implements View.OnClickListener,
room = room + "@" + server;
if (this.account != null && this.room != null)
if (!account.equals(this.account) || !room.equals(this.room)) {
MUCManager.getInstance().removeRoom(this.account, this.room);
MUCManager.getInstance()
.removeRoom(this.account, this.room);
MessageManager.getInstance().closeChat(this.account,
this.room);
NotificationManager.getInstance()
.removeMessageNotification(this.account, this.room);
}
MUCManager.getInstance()
.createRoom(account, room, nick, password, join);
MUCManager.getInstance().createRoom(account, room, nick, password,
join);
finish();
break;
default:
......@@ -229,18 +205,6 @@ public class MUCEditor extends ManagedActivity implements View.OnClickListener,
return name;
}
@Override
protected Dialog onCreateDialog(int id) {
super.onCreateDialog(id);
switch (id) {
case DIALOG_MUC_INVITE_ID:
return new ConfirmDialogBuilder(this, DIALOG_MUC_INVITE_ID, this)
.setMessage(roomInvite.getConfirmation()).create();
default:
return null;
}
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
......@@ -261,37 +225,6 @@ public class MUCEditor extends ManagedActivity implements View.OnClickListener,
selectedAccount = accountView.getSelectedItemPosition();
}
@Override
public void onAccept(DialogBuilder dialogBuilder) {
switch (dialogBuilder.getDialogId()) {
case DIALOG_MUC_INVITE_ID:
MUCManager.getInstance().removeInvite(roomInvite);
getIntent().setAction(null);
account = null;
room = null;
break;
}
}
@Override
public void onDecline(DialogBuilder dialogBuilder) {
switch (dialogBuilder.getDialogId()) {
case DIALOG_MUC_INVITE_ID:
MUCManager.getInstance().removeInvite(roomInvite);
finish();
break;
}
}
@Override
public void onCancel(DialogBuilder dialogBuilder) {
switch (dialogBuilder.getDialogId()) {
case DIALOG_MUC_INVITE_ID:
finish();
break;
}
}
public static Intent createIntent(Context context) {
return MUCEditor.createIntent(context, null, null);
}
......@@ -302,13 +235,6 @@ public class MUCEditor extends ManagedActivity implements View.OnClickListener,
.setAccount(account).setUser(room).build();
}
public static Intent createInviteIntent(Context context, String account,
String user) {
Intent intent = createIntent(context, account, user);
intent.setAction(ACTION_MUC_INVITE);
return intent;
}
private static String getAccount(Intent intent) {
return AccountIntentBuilder.getAccount(intent);
}
......
/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber 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 this program. If not, see http://www.gnu.org/licenses/.
*/
package com.xabber.android.ui;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import com.xabber.android.data.Application;
import com.xabber.android.data.extension.muc.MUCManager;
import com.xabber.android.data.extension.muc.RoomInvite;
import com.xabber.android.data.intent.AccountIntentBuilder;
import com.xabber.android.data.intent.EntityIntentBuilder;
import com.xabber.android.ui.helper.ManagedDialog;
import com.xabber.androiddev.R;
public class MUCInvite extends ManagedDialog {
private String account;
private String room;
private RoomInvite roomInvite;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
account = getAccount(intent);
room = getUser(intent);
roomInvite = MUCManager.getInstance().getInvite(account, room);
if (roomInvite == null) {
Application.getInstance().onError(R.string.ENTRY_IS_NOT_FOUND);
finish();
return;
}
setDialogMessage(roomInvite.getConfirmation());
setDialogTitle(R.string.subscription_request_message);
findViewById(android.R.id.button3).setVisibility(View.GONE);
}
@Override
public void onAccept() {
super.onAccept();
startActivity(MUCEditor.createIntent(this, account, room));
finish();
}
@Override
public void onDecline() {
super.onDecline();
MUCManager.getInstance().removeInvite(roomInvite);
finish();
}
public static Intent createIntent(Context context, String account,
String room) {
return new EntityIntentBuilder(context, MUCInvite.class)
.setAccount(account).setUser(room).build();
}
private static String getAccount(Intent intent) {
return AccountIntentBuilder.getAccount(intent);
}
private static String getUser(Intent intent) {
return EntityIntentBuilder.getUser(intent);
}
}
......@@ -40,7 +40,6 @@ import com.xabber.android.data.account.StatusMode;
import com.xabber.android.data.intent.AccountIntentBuilder;
import com.xabber.android.ui.adapter.StatusEditorAdapter;
import com.xabber.android.ui.adapter.StatusModeAdapter;
import com.xabber.android.ui.adapter.UpdatableAdapter;
import com.xabber.android.ui.helper.ManagedListActivity;
import com.xabber.androiddev.R;
......@@ -61,6 +60,7 @@ public class StatusEditor extends ManagedListActivity implements
private EditText statusTextView;
private SavedStatus actionWithItem;
private StatusEditorAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
......@@ -87,7 +87,8 @@ public class StatusEditor extends ManagedListActivity implements
listView.addHeaderView(header, null, false);
listView.setOnItemClickListener(this);
registerForContextMenu(listView);
setListAdapter(new StatusEditorAdapter(this));
adapter = new StatusEditorAdapter(this);
setListAdapter(adapter);
statusTextView = (EditText) header.findViewById(R.id.status_text);
statusModeView = (Spinner) header.findViewById(R.id.status_mode);
......@@ -146,7 +147,7 @@ public class StatusEditor extends ManagedListActivity implements
@Override
protected void onResume() {
super.onResume();
((UpdatableAdapter) getListAdapter()).onChange();
adapter.onChange();
}
@Override
......@@ -164,7 +165,7 @@ public class StatusEditor extends ManagedListActivity implements
switch (item.getItemId()) {
case OPTION_MENU_CLEAR_STATUSES_ID:
AccountManager.getInstance().clearSavedStatuses();
((UpdatableAdapter) getListAdapter()).onChange();
adapter.onChange();
return true;
}
return false;
......@@ -202,7 +203,7 @@ public class StatusEditor extends ManagedListActivity implements
return true;
case CONTEXT_MENU_REMOVE_STATUS_ID:
AccountManager.getInstance().removeSavedStatus(actionWithItem);
((UpdatableAdapter) getListAdapter()).onChange();
adapter.onChange();
return true;
}
return false;
......
......@@ -138,7 +138,7 @@ public class AccountToggleAdapter implements UpdatableAdapter {
* child.
* @return The data for the specified view.
*/
public Object getItemForView(View view) {
public String getItemForView(View view) {
if (view.getId() == R.id.status_mode)
view = (View) view.getParent();
for (int index = 0; index < linearLayout.getChildCount(); index++)
......
......@@ -17,38 +17,16 @@ package com.xabber.android.ui.adapter;
import java.util.ArrayList;
import java.util.Collection;
import android.app.Activity;
import android.text.Editable;
import android.text.TextWatcher;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.View.OnKeyListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import com.xabber.android.data.LogManager;
import com.xabber.android.data.SettingsManager;
import com.xabber.android.data.SettingsManager.SecurityOtrMode;
import com.xabber.android.data.entity.BaseEntity;
import com.xabber.android.data.extension.otr.OTRManager;
import com.xabber.android.data.extension.otr.SecurityLevel;
import com.xabber.android.data.message.AbstractChat;
import com.xabber.android.data.message.MessageManager;
import com.xabber.android.data.message.chat.ChatManager;
import com.xabber.android.data.roster.AbstractContact;
import com.xabber.android.data.roster.RosterManager;
import com.xabber.android.ui.helper.AbstractAvatarInflaterHelper;
import com.xabber.android.ui.helper.ContactTitleInflater;
import com.xabber.android.ui.widget.PageSwitcher;
import com.xabber.androiddev.R;
import com.xabber.android.ui.ChatViewerFragment;
import com.xabber.xmpp.address.Jid;
/**
......@@ -60,7 +38,7 @@ import com.xabber.xmpp.address.Jid;
public class ChatViewerAdapter extends BaseAdapter implements SaveStateAdapter,
UpdatableAdapter {
private final Activity activity;
private final FragmentActivity activity;
/**
* Intent sent while opening chat activity.
......@@ -74,39 +52,9 @@ public class ChatViewerAdapter extends BaseAdapter implements SaveStateAdapter,
private ArrayList<AbstractChat> activeChats;
/**
* Listener for click on title bar and send button.
*/
private OnClickListener onClickListener;
/**
* Listener for key press in edit view.
*/
private OnKeyListener onKeyListener;
/**
* Listener for actions in edit view.
*/
private OnEditorActionListener onEditorActionListener;
/**
* Listener for context menu in message list.
*/
private OnCreateContextMenuListener onCreateContextMenuListener;
/**
* Listen for text to be changed.
*/
private OnTextChangedListener onTextChangedListener;
private final AbstractAvatarInflaterHelper avatarInflaterHelper;
private final Animation shake;
public ChatViewerAdapter(Activity activity, String account, String user) {
public ChatViewerAdapter(FragmentActivity activity, String account,
String user) {
this.activity = activity;
avatarInflaterHelper = AbstractAvatarInflaterHelper
.createAbstractContactInflaterHelper();
activeChats = new ArrayList<AbstractChat>();
intent = MessageManager.getInstance().getOrCreateChat(account,
Jid.getBareAddress(user));
......@@ -116,58 +64,9 @@ public class ChatViewerAdapter extends BaseAdapter implements SaveStateAdapter,
intentPosition = -1;
else
intentPosition = activeChats.size();
onClickListener = null;
onKeyListener = null;
onEditorActionListener = null;
onCreateContextMenuListener = null;
onTextChangedListener = null;
shake = AnimationUtils.loadAnimation(activity, R.anim.shake);
onChange();
}
public OnClickListener getOnClickListener() {
return onClickListener;
}
public void setOnClickListener(OnClickListener onClickListener) {
this.onClickListener = onClickListener;
}
public OnKeyListener getOnKeyListener() {
return onKeyListener;
}
public void setOnKeyListener(OnKeyListener onKeyListener) {
this.onKeyListener = onKeyListener;
}
public OnEditorActionListener getOnEditorActionListener() {
return onEditorActionListener;
}
public void setOnEditorActionListener(
OnEditorActionListener onEditorActionListener) {
this.onEditorActionListener = onEditorActionListener;
}
public OnCreateContextMenuListener getOnCreateContextMenuListener() {
return onCreateContextMenuListener;
}
public void setOnCreateContextMenuListener(
OnCreateContextMenuListener onCreateContextMenuListener) {
this.onCreateContextMenuListener = onCreateContextMenuListener;
}
public OnTextChangedListener getOnTextChangedListener() {
return onTextChangedListener;
}
public void setOnTextChangedListener(
OnTextChangedListener onTextChangedListener) {
this.onTextChangedListener = onTextChangedListener;
}
@Override
public int getCount() {
return activeChats.size();
......@@ -187,116 +86,50 @@ public class ChatViewerAdapter extends BaseAdapter implements SaveStateAdapter,
public View getView(int position, View convertView, ViewGroup parent) {
View view;
final AbstractChat chat = (AbstractChat) getItem(position);
final ChatViewHolder chatViewHolder;
ChatViewerFragment fragment;
if (convertView == null) {
view = activity.getLayoutInflater().inflate(
R.layout.chat_viewer_item, parent, false);
ChatMessageAdapter chatMessageAdapter = new ChatMessageAdapter(
activity);
chatViewHolder = new ChatViewHolder(view, chatMessageAdapter);
chatViewHolder.list.setAdapter(chatViewHolder.chatMessageAdapter);
chatViewHolder.send.setOnClickListener(onClickListener);
chatViewHolder.title.setOnClickListener(onClickListener);
chatViewHolder.input.setOnKeyListener(onKeyListener);
chatViewHolder.input
.setOnEditorActionListener(onEditorActionListener);
chatViewHolder.input.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
if (onTextChangedListener != null)
onTextChangedListener.onTextChanged(
chatViewHolder.input, s);
}
});
chatViewHolder.list
.setOnCreateContextMenuListener(onCreateContextMenuListener);
view.setTag(chatViewHolder);
fragment = new ChatViewerFragment(activity);
view = fragment.getView();
view.setTag(fragment);
} else {
view = convertView;
chatViewHolder = (ChatViewHolder) view.getTag();
}
final String account = chat.getAccount();
final String user = chat.getUser();
final AbstractContact abstractContact = RosterManager.getInstance()
.getBestContact(account, user);
if (chat.equals(chatViewHolder.chatMessageAdapter.getAccount(),
chatViewHolder.chatMessageAdapter.getUser())) {
chatViewHolder.chatMessageAdapter.updateInfo();
} else {
if (chatViewHolder.chatMessageAdapter.getAccount() != null
&& chatViewHolder.chatMessageAdapter.getUser() != null)
saveState(view);
if (PageSwitcher.LOG)
LogManager.i(this, "Load " + view + " for "
+ chatViewHolder.chatMessageAdapter.getUser() + " in "
+ chatViewHolder.chatMessageAdapter.getAccount());
OnTextChangedListener temp = onTextChangedListener;
onTextChangedListener = null;
chatViewHolder.input.setText(ChatManager.getInstance()
.getTypedMessage(account, user));
chatViewHolder.input.setSelection(ChatManager.getInstance()
.getSelectionStart(account, user), ChatManager
.getInstance().getSelectionEnd(account, user));
onTextChangedListener = temp;
chatViewHolder.chatMessageAdapter.setChat(account, user);
chatViewHolder.list.setAdapter(chatViewHolder.list.getAdapter());
}
chatViewHolder.page.setText(activity.getString(R.string.chat_page,
position + 1, getCount()));
ContactTitleInflater.updateTitle(chatViewHolder.title, activity, abstractContact);
avatarInflaterHelper.updateAvatar(chatViewHolder.avatar,
abstractContact);
SecurityLevel securityLevel = OTRManager.getInstance()
.getSecurityLevel(chat.getAccount(), chat.getUser());
SecurityOtrMode securityOtrMode = SettingsManager.securityOtrMode();
if (securityLevel == SecurityLevel.plain
&& (securityOtrMode == SecurityOtrMode.disabled || securityOtrMode == SecurityOtrMode.manual)) {
chatViewHolder.security.setVisibility(View.GONE);
} else {
chatViewHolder.security.setVisibility(View.VISIBLE);
chatViewHolder.security
.setImageLevel(securityLevel.getImageLevel());
fragment = (ChatViewerFragment) view.getTag();
}
fragment.setChat(chat);
return view;
}
@Override
public void saveState(View view) {
ChatViewHolder chatViewHolder = (ChatViewHolder) view.getTag();
if (PageSwitcher.LOG)
LogManager.i(this, "Save " + view + " for "
+ chatViewHolder.chatMessageAdapter.getUser() + " in "
+ chatViewHolder.chatMessageAdapter.getAccount());
ChatManager.getInstance().setTyped(
chatViewHolder.chatMessageAdapter.getAccount(),
chatViewHolder.chatMessageAdapter.getUser(),
chatViewHolder.input.getText().toString(),
chatViewHolder.input.getSelectionStart(),
chatViewHolder.input.getSelectionEnd());
((ChatViewerFragment) view.getTag()).saveState();
}
@Override
public void hidePages(View view) {
((ChatViewerFragment) view.getTag()).hidePages();
}
@Override
public void showPages(View view) {
((ChatViewerFragment) view.getTag()).showPages();
}
/**
* Must be called on changes in chat (message sent, received, etc.).
*/
public void onChatChange(View view, boolean incomingMessage) {
ChatViewHolder holder = (ChatViewHolder) view.getTag();
if (incomingMessage)
holder.nameHolder.startAnimation(shake);
holder.chatMessageAdapter.onChange();
((ChatViewerFragment) view.getTag()).onChatChange(incomingMessage);
}
/**
* Must be called on changes in chat (message sent, received, etc.).
*/
public void onPrepareOptionsMenu(View view, Menu menu) {
((ChatViewerFragment) view.getTag()).onPrepareOptionsMenu(menu);
}
public void insertText(View view, String text) {
((ChatViewerFragment) view.getTag()).insertText(text);
}
@Override
......@@ -315,30 +148,11 @@ public class ChatViewerAdapter extends BaseAdapter implements SaveStateAdapter,
notifyDataSetChanged();
}
private static class ChatViewHolder {
final TextView page;
final View title;
final View nameHolder;
final ImageView avatar;
final ImageView security;
final View send;
final EditText input;
final ListView list;
final ChatMessageAdapter chatMessageAdapter;
public ChatViewHolder(View view, ChatMessageAdapter chatMessageAdapter) {
page = (TextView) view.findViewById(R.id.chat_page);
title = view.findViewById(R.id.title);
nameHolder = title.findViewById(R.id.name_holder);
avatar = (ImageView) title.findViewById(R.id.avatar);
security = (ImageView) title.findViewById(R.id.security);
send = view.findViewById(R.id.chat_send);
input = (EditText) view.findViewById(R.id.chat_input);
list = (ListView) view.findViewById(android.R.id.list);
this.chatMessageAdapter = chatMessageAdapter;
}
public int getPosition(String account, String user) {
for (int position = 0; position < activeChats.size(); position++)
if (activeChats.get(position).equals(account, user))
return position;
return -1;
}
}
......@@ -22,13 +22,9 @@ import java.util.Date;
import java.util.Map.Entry;
import java.util.TreeMap;
import android.app.ListActivity;
import android.app.Activity;
import android.os.Handler;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.TextView;
import android.widget.ListView;
import com.xabber.android.data.SettingsManager;
import com.xabber.android.data.account.AccountManager;
......@@ -42,7 +38,6 @@ import com.xabber.android.data.roster.AbstractContact;
import com.xabber.android.data.roster.GroupManager;
import com.xabber.android.data.roster.RosterContact;
import com.xabber.android.data.roster.RosterManager;
import com.xabber.androiddev.R;
/**
* Adapter for contact list in the main activity.
......@@ -59,36 +54,6 @@ public class ContactListAdapter extends
*/
private static final long REFRESH_INTERVAL = 1000;
/**
* View with information shown on empty contact list.
*/
private final View infoView;
/**
* Image view with connected icon.
*/
private View connectedView;
/**
* Image view with disconnected icon.
*/
private View disconnectedView;
/**
* View with help text.
*/
private TextView textView;
/**
* Button to apply help text.
*/
private Button buttonView;
/**
* Animation for disconnected view.
*/
private Animation animation;
/**
* Handler for deferred refresh.
*/
......@@ -114,24 +79,13 @@ public class ContactListAdapter extends
*/
private Date nextRefresh;
public ContactListAdapter(ListActivity activity) {
super(activity, activity.getListView(), new ChatContactInflater(
activity), GroupManager.getInstance());
infoView = activity.findViewById(R.id.info);
if (infoView != null) {
connectedView = infoView.findViewById(R.id.connected);
disconnectedView = infoView.findViewById(R.id.disconnected);
textView = (TextView) infoView.findViewById(R.id.text);
buttonView = (Button) infoView.findViewById(R.id.button);
animation = AnimationUtils.loadAnimation(activity,
R.anim.connection);
} else {
connectedView = null;
disconnectedView = null;
textView = null;
buttonView = null;
animation = null;
}
private final OnContactListChangedListener listener;
public ContactListAdapter(Activity activity, ListView listView,
OnContactListChangedListener listener) {
super(activity, listView, new ChatContactInflater(activity),
GroupManager.getInstance());
this.listener = listener;
handler = new Handler();
refreshLock = new Object();
refreshRequested = false;
......@@ -220,12 +174,12 @@ public class ContactListAdapter extends
/**
* Whether there is at least one contact.
*/
boolean hasContact = false;
boolean hasContacts = false;
/**
* Whether there is at least one visible contact.
*/
boolean hasVisible = false;
boolean hasVisibleContacts = false;
for (String account : AccountManager.getInstance().getAccounts())
accounts.put(account, null);
......@@ -274,7 +228,7 @@ public class ContactListAdapter extends
for (RosterContact rosterContact : rosterContacts) {
if (!rosterContact.isEnabled())
continue;
hasContact = true;
hasContacts = true;
final boolean online = rosterContact.getStatusMode().isOnline();
final String account = rosterContact.getAccount();
final TreeMap<String, AbstractChat> users = abstractChats
......@@ -287,7 +241,7 @@ public class ContactListAdapter extends
if (showActiveChats && abstractChat != null
&& abstractChat.isActive()) {
activeChats.setNotEmpty();
hasVisible = true;
hasVisibleContacts = true;
if (activeChats.isExpanded())
activeChats.addAbstractContact(rosterContact);
activeChats.increment(online);
......@@ -298,7 +252,7 @@ public class ContactListAdapter extends
continue;
if (addContact(rosterContact, online, accounts, groups,
contacts, showAccounts, showGroups, showOffline))
hasVisible = true;
hasVisibleContacts = true;
}
for (TreeMap<String, AbstractChat> users : abstractChats.values())
for (AbstractChat abstractChat : users.values()) {
......@@ -310,7 +264,7 @@ public class ContactListAdapter extends
abstractContact = new ChatContact(abstractChat);
if (showActiveChats && abstractChat.isActive()) {
activeChats.setNotEmpty();
hasVisible = true;
hasVisibleContacts = true;
if (activeChats.isExpanded())
activeChats.addAbstractContact(abstractContact);
activeChats.increment(false);
......@@ -330,14 +284,14 @@ public class ContactListAdapter extends
group = GroupManager.NO_GROUP;
online = false;
}
hasVisible = true;
hasVisibleContacts = true;
addContact(abstractContact, group, online, accounts,
groups, contacts, showAccounts, showGroups);
}
// Remove empty groups, sort and apply structure.
baseEntities.clear();
if (hasVisible) {
if (hasVisibleContacts) {
if (showActiveChats) {
if (!activeChats.isEmpty()) {
if (showAccounts || showGroups)
......@@ -417,89 +371,12 @@ public class ContactListAdapter extends
Collections.sort(baseEntities, comparator);
this.baseEntities.clear();
this.baseEntities.addAll(baseEntities);
hasVisible = baseEntities.size() > 0;
}
if (infoView != null) {
if (hasVisible) {
infoView.setVisibility(View.GONE);
disconnectedView.clearAnimation();
} else {
infoView.setVisibility(View.VISIBLE);
final int text;
final int button;
final ContactListState state;
if (filterString != null) {
if (commonState == CommonState.online)
state = ContactListState.online;
else if (commonState == CommonState.roster
|| commonState == CommonState.connecting)
state = ContactListState.connecting;
else
state = ContactListState.offline;
text = R.string.application_state_no_online;
button = 0;
} else if (hasContact) {
state = ContactListState.online;
text = R.string.application_state_no_online;
button = R.string.application_action_no_online;
} else if (commonState == CommonState.online) {
state = ContactListState.online;
text = R.string.application_state_no_contacts;
button = R.string.application_action_no_contacts;
} else if (commonState == CommonState.roster) {
state = ContactListState.connecting;
text = R.string.application_state_roster;
button = 0;
} else if (commonState == CommonState.connecting) {
state = ContactListState.connecting;
text = R.string.application_state_connecting;
button = 0;
} else if (commonState == CommonState.waiting) {
state = ContactListState.offline;
text = R.string.application_state_waiting;
button = R.string.application_action_waiting;
} else if (commonState == CommonState.offline) {
state = ContactListState.offline;
text = R.string.application_state_offline;
button = R.string.application_action_offline;
} else if (commonState == CommonState.disabled) {
state = ContactListState.offline;
text = R.string.application_state_disabled;
button = R.string.application_action_disabled;
} else if (commonState == CommonState.empty) {
state = ContactListState.offline;
text = R.string.application_state_empty;
button = R.string.application_action_empty;
} else {
throw new IllegalStateException();
}
if (state == ContactListState.offline) {
connectedView.setVisibility(View.INVISIBLE);
disconnectedView.setVisibility(View.VISIBLE);
disconnectedView.clearAnimation();
} else if (state == ContactListState.connecting) {
connectedView.setVisibility(View.VISIBLE);
disconnectedView.setVisibility(View.VISIBLE);
if (disconnectedView.getAnimation() == null)
disconnectedView.startAnimation(animation);
} else if (state == ContactListState.online) {
connectedView.setVisibility(View.VISIBLE);
disconnectedView.setVisibility(View.INVISIBLE);
disconnectedView.clearAnimation();
}
textView.setText(text);
if (button == 0) {
buttonView.setVisibility(View.GONE);
} else {
buttonView.setVisibility(View.VISIBLE);
buttonView.setText(button);
buttonView.setTag(Integer.valueOf(button));
}
}
hasVisibleContacts = baseEntities.size() > 0;
}
super.onChange();
listener.onContactListChanged(commonState, hasContacts, hasVisibleContacts,
filterString != null);
synchronized (refreshLock) {
nextRefresh = new Date(new Date().getTime() + REFRESH_INTERVAL);
......@@ -515,4 +392,17 @@ public class ContactListAdapter extends
onChange();
}
/**
* Listener for contact list appearance changes.
*
* @author alexander.ivanov
*
*/
public interface OnContactListChangedListener {
void onContactListChanged(CommonState commonState, boolean hasContacts,
boolean hasVisibleContacts, boolean isFilterEnabled);
}
}
......@@ -36,4 +36,18 @@ public interface SaveStateAdapter extends Adapter {
*/
void saveState(View view);
/**
* Requests to hide pages indicator.
*
* @param view
*/
void hidePages(View view);
/**
* Show pages indicator.
*
* @param view
*/
void showPages(View view);
}
/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber 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 this program. If not, see http://www.gnu.org/licenses/.
*/
package com.xabber.android.ui.dialog;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
/**
* Base dialog fragment.
*
* CONVENTION: Subclass should implement <code>newInstance</code> static method.
* Activities or Fragments should use this method to instantiate DialogFragment.
*
* @author alexander.ivanov
*
*/
public abstract class AbstractDialogFragment extends DialogFragment {
private Bundle initArguments() {
Bundle bundle = getArguments();
if (bundle == null) {
bundle = new Bundle();
setArguments(bundle);
}
return bundle;
}
protected AbstractDialogFragment putAgrument(String key, String value) {
initArguments().putString(key, value);
return this;
}
protected AbstractDialogFragment putAgrument(String key,
ArrayList<String> value) {
initArguments().putStringArrayList(key, value);
return this;
}
protected AbstractDialogFragment putAgrument(String key, boolean value) {
initArguments().putBoolean(key, value);
return this;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Builder builder = getBuilder();
return getDialog(builder);
}
/**
* Constructs {@link AlertDialog.Builder} instance.
*
* @return
*/
protected abstract Builder getBuilder();
/**
* Constructs {@link Dialog} instance.
*
* @param builder
* @return
*/
protected Dialog getDialog(Builder builder) {
return builder.create();
}
}
package com.xabber.android.ui.dialog;
import java.util.ArrayList;
import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.view.ViewGroup;
import com.xabber.android.data.roster.RosterContact;
import com.xabber.android.data.roster.RosterManager;
import com.xabber.android.ui.adapter.AccountChooseAdapter;
public class AccountChooseDialogFragment extends AbstractDialogFragment {
private static final String USER = "USER";
private static final String TEXT = "TEXT";
/**
* @param user
* @param text
* @return
*/
public static DialogFragment newInstance(String user, String text) {
return new AccountChooseDialogFragment().putAgrument(USER, user)
.putAgrument(TEXT, text);
}
private String user;
private String text;
@Override
protected Builder getBuilder() {
user = getArguments().getString(USER);
text = getArguments().getString(TEXT);
final Adapter adapter = new Adapter(getActivity());
Builder builder = new Builder(getActivity());
builder.setSingleChoiceItems(adapter, -1, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String account = (String) adapter.getItem(which);
OnChoosedListener listener = (OnChoosedListener) getActivity();
listener.onChoosed(account, user, text);
}
});
return builder;
}
private class Adapter extends AccountChooseAdapter {
public Adapter(Activity activity) {
super(activity);
ArrayList<String> available = new ArrayList<String>();
for (RosterContact check : RosterManager.getInstance()
.getContacts())
if (check.isEnabled() && check.getUser().equals(user))
available.add(check.getAccount());
if (!available.isEmpty()) {
accounts.clear();
accounts.addAll(available);
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return getDropDownView(position, convertView, parent);
}
}
public interface OnChoosedListener {
void onChoosed(String account, String user, String text);
}
}
/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber 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 this program. If not, see http://www.gnu.org/licenses/.
*/
package com.xabber.android.ui.dialog;
import java.io.File;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
import com.xabber.android.data.Application;
import com.xabber.android.data.NetworkException;
import com.xabber.android.data.account.AccountManager;
import com.xabber.android.data.message.MessageManager;
import com.xabber.android.data.roster.RosterManager;
import com.xabber.androiddev.R;
public class ChatExportDialogFragment extends ConfirmDialogFragment {
private static final String ACCOUNT = "ACCOUNT";
private static final String USER = "USER";
/**
* @param account
* @param user
* @return
*/
public static DialogFragment newInstance(String account, String user) {
return new ChatExportDialogFragment().putAgrument(ACCOUNT, account)
.putAgrument(USER, user);
}
private String account;
private String user;
private EditText nameView;
private CheckBox sendView;
@Override
protected Builder getBuilder() {
account = getArguments().getString(ACCOUNT);
user = getArguments().getString(USER);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.export_chat_title);
View layout = getActivity().getLayoutInflater().inflate(
R.layout.export_chat, null);
nameView = (EditText) layout.findViewById(R.id.name);
sendView = (CheckBox) layout.findViewById(R.id.send);
nameView.setText(getString(R.string.export_chat_mask, AccountManager
.getInstance().getVerboseName(account), RosterManager
.getInstance().getName(account, user)));
builder.setView(layout);
return builder;
}
@Override
protected boolean onPositiveClick() {
String name = nameView.getText().toString();
if ("".equals(name))
return false;
new ChatExportAsyncTask(account, user, name, sendView.isChecked())
.execute();
return true;
}
private class ChatExportAsyncTask extends AsyncTask<Void, Void, File> {
private final String account;
private final String user;
private final String name;
private final boolean send;
public ChatExportAsyncTask(String account, String user, String name,
boolean send) {
this.account = account;
this.user = user;
this.name = name;
this.send = send;
}
@Override
protected File doInBackground(Void... params) {
try {
return MessageManager.getInstance().exportChat(account, user,
name);
} catch (NetworkException e) {
Application.getInstance().onError(e);
return null;
}
}
@Override
public void onPostExecute(File result) {
if (result == null)
return;
// TODO: Use notification bar to notify about success.
if (send) {
Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("text/plain");
Uri uri = Uri.fromFile(result);
intent.putExtra(android.content.Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(intent,
getString(R.string.export_chat)));
} else {
Toast.makeText(getActivity(), R.string.export_chat_done,
Toast.LENGTH_LONG).show();
}
}
}
}
/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber 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 this program. If not, see http://www.gnu.org/licenses/.
*/
package com.xabber.android.ui.dialog;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnShowListener;
import android.os.Build;
import android.view.View;
import android.widget.Button;
/**
* Base yes / no dialog fragment.
*
* Provides callback methods and option to abort dialog dismissing on button
* click (starting from FROYO version).
*
* @author alexander.ivanov
*
*/
public abstract class ConfirmDialogFragment extends AbstractDialogFragment {
private final OnClickListener positiveListener = new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (onPositiveClick())
supportDismiss(dialog);
}
};
private final OnClickListener neutralListener = new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (onNegativeClicked())
supportDismiss(dialog);
}
};
private final OnClickListener negativeListener = new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (onNegativeClicked())
supportDismiss(dialog);
}
};
@Override
protected Dialog getDialog(Builder builder) {
if (hasPositiveButton())
builder.setPositiveButton(getPositiveTextId(), positiveListener);
if (hasNeutralButton())
builder.setNeutralButton(getNeutralTextId(), neutralListener);
if (hasNegativeButton())
builder.setNegativeButton(getNegativeTextId(), negativeListener);
AlertDialog dialog = builder.create();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO)
setOnShowListener(dialog);
return dialog;
}
private void supportDismiss(DialogInterface dialog) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO)
dialog.dismiss();
}
@TargetApi(Build.VERSION_CODES.FROYO)
private void setOnShowListener(final AlertDialog alertDialog) {
alertDialog.setOnShowListener(new OnShowListener() {
private void setListener(final int whichButton,
final OnClickListener listener) {
Button button = alertDialog.getButton(whichButton);
if (button == null)
return;
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onClick(alertDialog, whichButton);
}
});
}
@Override
public void onShow(DialogInterface dialog) {
setListener(AlertDialog.BUTTON_POSITIVE, positiveListener);
setListener(AlertDialog.BUTTON_NEUTRAL, neutralListener);
setListener(AlertDialog.BUTTON_NEGATIVE, negativeListener);
}
});
}
protected boolean hasPositiveButton() {
return true;
}
protected boolean hasNeutralButton() {
return false;
}
protected boolean hasNegativeButton() {
return true;
}
protected int getPositiveTextId() {
return android.R.string.ok;
}
protected int getNeutralTextId() {
return android.R.string.unknownName;
}
protected int getNegativeTextId() {
return android.R.string.cancel;
}
/**
* Processes positive button click.
*
* @return Whether dialog can be dismissed.
*/
protected boolean onPositiveClick() {
return true;
}
/**
* Processes neutral button click.
*
* @return Whether dialog can be dismissed.
*/
protected boolean onNeutralClicked() {
return true;
}
/**
* Processes negative button click.
*
* @return Whether dialog can be dismissed.
*/
protected boolean onNegativeClicked() {
return true;
}
}
package com.xabber.android.ui.dialog;
import android.app.AlertDialog.Builder;
import android.support.v4.app.DialogFragment;
import com.xabber.android.data.Application;
import com.xabber.android.data.NetworkException;
import com.xabber.android.data.account.AccountManager;
import com.xabber.android.data.roster.RosterManager;
import com.xabber.androiddev.R;
public class ContactDeleteDialogFragment extends ConfirmDialogFragment {
private static final String ACCOUNT = "ACCOUNT";
private static final String USER = "USER";
/**
* @param account
* @param user
* @return
*/
public static DialogFragment newInstance(String account, String user) {
return new ContactDeleteDialogFragment().putAgrument(ACCOUNT, account)
.putAgrument(USER, user);
}
private String user;
private String account;
@Override
protected Builder getBuilder() {
user = getArguments().getString(USER);
account = getArguments().getString(ACCOUNT);
return new Builder(getActivity()).setMessage(getString(
R.string.contact_delete_confirm, RosterManager.getInstance()
.getName(account, user), AccountManager.getInstance()
.getVerboseName(account)));
}
@Override
protected boolean onPositiveClick() {
try {
RosterManager.getInstance().removeContact(account, user);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
return true;
}
}
package com.xabber.android.ui.dialog;
import android.app.AlertDialog.Builder;
import android.support.v4.app.DialogFragment;
import com.xabber.android.data.SettingsManager;
import com.xabber.android.data.account.AccountManager;
import com.xabber.androiddev.R;
public class ContactIntegrationDialogFragment extends ConfirmDialogFragment {
public static DialogFragment newInstance() {
return new ContactIntegrationDialogFragment();
}
@Override
protected Builder getBuilder() {
return new Builder(getActivity())
.setMessage(R.string.contact_integration_suggest);
}
@Override
protected boolean onPositiveClick() {
SettingsManager.setContactIntegrationSuggested();
for (String account : AccountManager.getInstance().getAllAccounts())
AccountManager.getInstance().setSyncable(account, true);
return true;
}
@Override
protected boolean onNegativeClicked() {
SettingsManager.setContactIntegrationSuggested();
return true;
}
}
/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber 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 this program. If not, see http://www.gnu.org/licenses/.
*/
package com.xabber.android.ui.dialog;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.xabber.androiddev.R;
public class GroupAddDialogFragment extends ConfirmDialogFragment {
private static final String GROUPS = "GROUPS";
/**
* @param account
* can be <code>null</code> to be used for all accounts.
* @param group
* can be <code>null</code> to be used for "no group".
* @return
*/
public static DialogFragment newInstance(ArrayList<String> groups) {
return new GroupAddDialogFragment().putAgrument(GROUPS, groups);
}
private ArrayList<String> groups;
private EditText nameView;
@Override
protected Builder getBuilder() {
groups = getArguments().getStringArrayList(GROUPS);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.group_add);
View layout = getActivity().getLayoutInflater().inflate(
R.layout.group_name, null);
nameView = (EditText) layout.findViewById(R.id.group_name);
builder.setView(layout);
return builder;
}
@Override
protected boolean onPositiveClick() {
String group = nameView.getText().toString();
if ("".equals(group)) {
Toast.makeText(getActivity(), getString(R.string.group_is_empty),
Toast.LENGTH_LONG).show();
return false;
}
if (groups.contains(group)) {
Toast.makeText(getActivity(), getString(R.string.group_exists),
Toast.LENGTH_LONG).show();
return false;
}
((OnGroupAddConfirmed) getActivity()).onGroupAddConfirmed(group);
return true;
}
public interface OnGroupAddConfirmed {
void onGroupAddConfirmed(String group);
}
}
package com.xabber.android.ui.dialog;
import android.app.AlertDialog.Builder;
import android.support.v4.app.DialogFragment;
import com.xabber.android.data.Application;
import com.xabber.android.data.NetworkException;
import com.xabber.android.data.roster.RosterManager;
import com.xabber.androiddev.R;
public class GroupDeleteDialogFragment extends ConfirmDialogFragment {
private static final String ACCOUNT = "ACCOUNT";
private static final String GROUP = "GROUP";
/**
* @param account
* can be <code>null</code> to be used for all accounts.
* @param group
* @return
*/
public static DialogFragment newInstance(String account, String group) {
return new GroupDeleteDialogFragment().putAgrument(ACCOUNT, account)
.putAgrument(GROUP, group);
}
private String group;
private String account;
@Override
protected Builder getBuilder() {
group = getArguments().getString(GROUP);
account = getArguments().getString(ACCOUNT);
return new Builder(getActivity()).setMessage(getString(
R.string.group_remove_confirm, group));
}
@Override
protected boolean onPositiveClick() {
try {
if (account == null)
RosterManager.getInstance().removeGroup(group);
else
RosterManager.getInstance().removeGroup(account, group);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
return true;
}
}
/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber 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 this program. If not, see http://www.gnu.org/licenses/.
*/
package com.xabber.android.ui.dialog;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.xabber.android.data.Application;
import com.xabber.android.data.NetworkException;
import com.xabber.android.data.roster.RosterManager;
import com.xabber.androiddev.R;
public class GroupRenameDialogFragment extends ConfirmDialogFragment {
private static final String ACCOUNT = "ACCOUNT";
private static final String GROUP = "GROUP";
/**
* @param account
* can be <code>null</code> to be used for all accounts.
* @param group
* can be <code>null</code> to be used for "no group".
* @return
*/
public static DialogFragment newInstance(String account, String group) {
return new GroupRenameDialogFragment().putAgrument(ACCOUNT, account)
.putAgrument(GROUP, group);
}
private String group;
private String account;
private EditText nameView;
@Override
protected Builder getBuilder() {
group = getArguments().getString(GROUP);
account = getArguments().getString(ACCOUNT);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.group_rename);
View layout = getActivity().getLayoutInflater().inflate(
R.layout.group_name, null);
nameView = (EditText) layout.findViewById(R.id.group_name);
nameView.setText(group == null ? "" : group);
builder.setView(layout);
return builder;
}
@Override
protected boolean onPositiveClick() {
String newName = nameView.getText().toString();
if ("".equals(newName)) {
Toast.makeText(getActivity(), getString(R.string.group_is_empty),
Toast.LENGTH_LONG).show();
return false;
}
try {
if (account == null)
RosterManager.getInstance().renameGroup(group, newName);
else
RosterManager.getInstance()
.renameGroup(account, group, newName);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
return true;
}
}
package com.xabber.android.ui.dialog;
import android.app.AlertDialog.Builder;
import android.support.v4.app.DialogFragment;
import com.xabber.android.data.account.AccountManager;
import com.xabber.android.data.extension.muc.MUCManager;
import com.xabber.android.data.message.MessageManager;
import com.xabber.android.data.notification.NotificationManager;
import com.xabber.android.data.roster.RosterManager;
import com.xabber.androiddev.R;
public class MUCDeleteDialogFragment extends ConfirmDialogFragment {
private static final String ACCOUNT = "ACCOUNT";
private static final String USER = "USER";
/**
* @param account
* @param user
* @return
*/
public static DialogFragment newInstance(String account, String user) {
return new MUCDeleteDialogFragment().putAgrument(ACCOUNT, account)
.putAgrument(USER, user);
}
private String user;
private String account;
@Override
protected Builder getBuilder() {
user = getArguments().getString(USER);
account = getArguments().getString(ACCOUNT);
return new Builder(getActivity()).setMessage(getString(
R.string.muc_delete_confirm, RosterManager.getInstance()
.getName(account, user), AccountManager.getInstance()
.getVerboseName(account)));
}
@Override
protected boolean onPositiveClick() {
MUCManager.getInstance().removeRoom(account, user);
MessageManager.getInstance().closeChat(account, user);
NotificationManager.getInstance().removeMessageNotification(account,
user);
return true;
}
}
package com.xabber.android.ui.dialog;
import android.app.AlertDialog.Builder;
import android.support.v4.app.DialogFragment;
import com.xabber.android.data.SettingsManager;
import com.xabber.androiddev.R;
public class StartAtBootDialogFragment extends ConfirmDialogFragment {
public static DialogFragment newInstance() {
return new StartAtBootDialogFragment();
}
@Override
protected Builder getBuilder() {
return new Builder(getActivity())
.setMessage(R.string.start_at_boot_suggest);
}
@Override
protected boolean onPositiveClick() {
SettingsManager.setStartAtBootSuggested();
SettingsManager.setConnectionStartAtBoot(true);
return true;
}
@Override
protected boolean onNegativeClicked() {
SettingsManager.setStartAtBootSuggested();
return true;
}
}
......@@ -52,7 +52,7 @@ public abstract class BaseListEditor<T> extends ManagedListActivity implements
private T actionWith;
private BaseListEditorAdapter<T> adapter;
protected BaseListEditorAdapter<T> adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
......
/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber 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 this program. If not, see http://www.gnu.org/licenses/.
*/
package com.xabber.android.ui.helper;
import android.support.v4.app.FragmentActivity;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.SubMenu;
import com.xabber.android.data.Application;
import com.xabber.android.data.NetworkException;
import com.xabber.android.data.SettingsManager;
import com.xabber.android.data.account.AccountItem;
import com.xabber.android.data.account.AccountManager;
import com.xabber.android.data.account.StatusMode;
import com.xabber.android.data.connection.ConnectionState;
import com.xabber.android.data.extension.muc.MUCManager;
import com.xabber.android.data.message.MessageManager;
import com.xabber.android.data.notification.NotificationManager;
import com.xabber.android.data.roster.AbstractContact;
import com.xabber.android.data.roster.GroupManager;
import com.xabber.android.data.roster.PresenceManager;
import com.xabber.android.data.roster.ShowOfflineMode;
import com.xabber.android.ui.AccountEditor;
import com.xabber.android.ui.ChatViewer;
import com.xabber.android.ui.ContactAdd;
import com.xabber.android.ui.ContactEditor;
import com.xabber.android.ui.ContactViewer;
import com.xabber.android.ui.MUCEditor;
import com.xabber.android.ui.StatusEditor;
import com.xabber.android.ui.adapter.UpdatableAdapter;
import com.xabber.android.ui.dialog.ContactDeleteDialogFragment;
import com.xabber.android.ui.dialog.GroupDeleteDialogFragment;
import com.xabber.android.ui.dialog.GroupRenameDialogFragment;
import com.xabber.android.ui.dialog.MUCDeleteDialogFragment;
import com.xabber.androiddev.R;
/**
* Helper class for context menu creation.
*
* @author alexander.ivanov
*
*/
public class ContextMenuHelper {
private ContextMenuHelper() {
}
public static void createContactContextMenu(
final FragmentActivity activity, final UpdatableAdapter adapter,
AbstractContact abstractContact, ContextMenu menu) {
final String account = abstractContact.getAccount();
final String user = abstractContact.getUser();
menu.setHeaderTitle(abstractContact.getName());
menu.add(R.string.chat_viewer).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
MessageManager.getInstance().openChat(account, user);
activity.startActivity(ChatViewer.createIntent(
activity, account, user));
return true;
}
});
if (MUCManager.getInstance().hasRoom(account, user)) {
if (!MUCManager.getInstance().inUse(account, user))
menu.add(R.string.muc_edit).setIntent(
MUCEditor.createIntent(activity, account, user));
menu.add(R.string.muc_delete).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
MUCDeleteDialogFragment.newInstance(account, user)
.show(activity.getSupportFragmentManager(),
"MUC_DELETE");
return true;
}
});
if (MUCManager.getInstance().isDisabled(account, user))
menu.add(R.string.muc_join).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
MUCManager.getInstance().joinRoom(account,
user, true);
return true;
}
});
else
menu.add(R.string.muc_leave).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
MUCManager.getInstance().leaveRoom(account,
user);
MessageManager.getInstance().closeChat(account,
user);
NotificationManager.getInstance()
.removeMessageNotification(account,
user);
adapter.onChange();
return true;
}
});
} else {
menu.add(R.string.contact_viewer).setIntent(
ContactViewer.createIntent(activity, account, user));
menu.add(R.string.contact_editor).setIntent(
ContactEditor.createIntent(activity, account, user));
menu.add(R.string.contact_delete).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
ContactDeleteDialogFragment.newInstance(account,
user).show(
activity.getSupportFragmentManager(),
"CONTACT_DELETE");
return true;
}
});
if (MessageManager.getInstance().hasActiveChat(account, user))
menu.add(R.string.close_chat).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
MessageManager.getInstance().closeChat(account,
user);
NotificationManager.getInstance()
.removeMessageNotification(account,
user);
adapter.onChange();
return true;
}
});
if (abstractContact.getStatusMode() == StatusMode.unsubscribed)
menu.add(R.string.request_subscription)
.setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
try {
PresenceManager.getInstance()
.requestSubscription(
account, user);
} catch (NetworkException e) {
Application.getInstance()
.onError(e);
}
return true;
}
});
}
if (PresenceManager.getInstance().hasSubscriptionRequest(account, user)) {
menu.add(R.string.accept_subscription).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
try {
PresenceManager.getInstance()
.acceptSubscription(account, user);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
activity.startActivity(ContactEditor.createIntent(
activity, account, user));
return true;
}
});
menu.add(R.string.discard_subscription).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
try {
PresenceManager.getInstance()
.discardSubscription(account, user);
} catch (NetworkException e) {
Application.getInstance().onError(e);
}
return true;
}
});
}
}
public static void createGroupContextMenu(final FragmentActivity activity,
UpdatableAdapter adapter, final String account, final String group,
ContextMenu menu) {
menu.setHeaderTitle(GroupManager.getInstance().getGroupName(account,
group));
if (group != GroupManager.ACTIVE_CHATS && group != GroupManager.IS_ROOM) {
menu.add(R.string.group_rename).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
GroupRenameDialogFragment.newInstance(
account == GroupManager.NO_ACCOUNT ? null
: account,
group == GroupManager.NO_GROUP ? null
: group).show(
activity.getSupportFragmentManager(),
"GROUP_RENAME");
return true;
}
});
if (group != GroupManager.NO_GROUP)
menu.add(R.string.group_remove).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
GroupDeleteDialogFragment
.newInstance(
account == GroupManager.NO_ACCOUNT ? null
: account, group)
.show(activity
.getSupportFragmentManager(),
"GROUP_DELETE");
return true;
}
});
}
createOfflineModeContextMenu(adapter, account, group, menu);
}
public static void createAccountContextMenu(
final FragmentActivity activity, UpdatableAdapter adapter,
final String account, ContextMenu menu) {
menu.setHeaderTitle(AccountManager.getInstance()
.getVerboseName(account));
AccountItem accountItem = AccountManager.getInstance().getAccount(
account);
ConnectionState state = accountItem.getState();
if (state == ConnectionState.waiting)
menu.add(R.string.account_reconnect).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (AccountManager.getInstance()
.getAccount(account).updateConnection(true))
AccountManager.getInstance().onAccountChanged(
account);
return true;
}
});
menu.add(R.string.status_editor).setIntent(
StatusEditor.createIntent(activity, account));
menu.add(R.string.account_editor).setIntent(
AccountEditor.createIntent(activity, account));
if (state.isConnected()) {
menu.add(R.string.contact_viewer).setOnMenuItemClickListener(
new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
String user = AccountManager.getInstance()
.getAccount(account).getRealJid();
if (user == null)
Application.getInstance().onError(
R.string.NOT_CONNECTED);
else {
activity.startActivity(ContactViewer
.createIntent(activity, account, user));
}
return true;
}
});
menu.add(R.string.contact_add).setIntent(
ContactAdd.createIntent(activity, account));
}
if (SettingsManager.contactsShowAccounts())
createOfflineModeContextMenu(adapter, account, null, menu);
}
private static void createOfflineModeContextMenu(UpdatableAdapter adapter,
String account, String group, ContextMenu menu) {
SubMenu mapMode = menu.addSubMenu(R.string.show_offline_settings);
mapMode.setHeaderTitle(R.string.show_offline_settings);
MenuItem always = mapMode.add(R.string.show_offline_settings, 0, 0,
R.string.show_offline_always).setOnMenuItemClickListener(
new OfflineModeClickListener(adapter, account, group,
ShowOfflineMode.always));
MenuItem normal = mapMode.add(R.string.show_offline_settings, 0, 0,
R.string.show_offline_normal).setOnMenuItemClickListener(
new OfflineModeClickListener(adapter, account, group,
ShowOfflineMode.normal));
MenuItem never = mapMode.add(R.string.show_offline_settings, 0, 0,
R.string.show_offline_never).setOnMenuItemClickListener(
new OfflineModeClickListener(adapter, account, group,
ShowOfflineMode.never));
mapMode.setGroupCheckable(R.string.show_offline_settings, true, true);
ShowOfflineMode showOfflineMode = GroupManager.getInstance()
.getShowOfflineMode(account,
group == null ? GroupManager.IS_ACCOUNT : group);
if (showOfflineMode == ShowOfflineMode.always)
always.setChecked(true);
else if (showOfflineMode == ShowOfflineMode.normal)
normal.setChecked(true);
else if (showOfflineMode == ShowOfflineMode.never)
never.setChecked(true);
else
throw new IllegalStateException();
}
private static class OfflineModeClickListener implements
MenuItem.OnMenuItemClickListener {
private final UpdatableAdapter adapter;
private final String account;
private final String group;
private final ShowOfflineMode mode;
public OfflineModeClickListener(UpdatableAdapter adapter,
String account, String group, ShowOfflineMode mode) {
super();
this.adapter = adapter;
this.account = account;
this.group = group;
this.mode = mode;
}
@Override
public boolean onMenuItemClick(MenuItem item) {
GroupManager.getInstance().setShowOfflineMode(account,
group == null ? GroupManager.IS_ACCOUNT : group, mode);
adapter.onChange();
return true;
}
}
}
......@@ -14,9 +14,9 @@
*/
package com.xabber.android.ui.helper;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import com.xabber.android.data.ActivityManager;
......@@ -28,7 +28,7 @@ import com.xabber.android.data.ActivityManager;
* @author alexander.ivanov
*
*/
public abstract class ManagedActivity extends Activity {
public abstract class ManagedActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
......
......@@ -14,9 +14,11 @@
*/
package com.xabber.android.ui.helper;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.widget.ListAdapter;
import android.widget.ListView;
import com.xabber.android.data.ActivityManager;
......@@ -28,7 +30,7 @@ import com.xabber.android.data.ActivityManager;
* @author alexander.ivanov
*
*/
public abstract class ManagedListActivity extends ListActivity {
public abstract class ManagedListActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
......@@ -79,4 +81,12 @@ public abstract class ManagedListActivity extends ListActivity {
super.startActivityForResult(intent, requestCode);
}
public ListView getListView() {
return (ListView) findViewById(android.R.id.list);
}
public void setListAdapter(ListAdapter adapter) {
getListView().setAdapter(adapter);
}
}
......@@ -16,15 +16,11 @@ package com.xabber.android.ui.widget;
import android.content.Context;
import android.database.DataSetObserver;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.Adapter;
import android.widget.ListView;
import android.widget.Scroller;
......@@ -41,15 +37,10 @@ import com.xabber.androiddev.R;
* @author alexander.ivanov
*
*/
public class PageSwitcher extends ViewGroup implements AnimationListener {
public class PageSwitcher extends ViewGroup {
public static final boolean LOG = false;
/**
* Delay before hide pages.
*/
private static final long PAGES_HIDDER_DELAY = 1000;
/**
* Distance a touch can wander before we think the user is scrolling.
*/
......@@ -136,38 +127,6 @@ public class PageSwitcher extends ViewGroup implements AnimationListener {
*/
private Object previousVisibleObject;
/**
* Animation used to hide pages.
*/
private final Animation pagesHideAnimation;
/**
* Runnable called to hide pages.
*/
private final Runnable pagesHideRunnable = new Runnable() {
@Override
public void run() {
if (LOG)
LogManager.i(this, "hide pages");
handler.removeCallbacks(this);
if (selectedView != null)
selectedView.findViewById(R.id.chat_page).startAnimation(
pagesHideAnimation);
if (visibleView != null) {
visibleView.findViewById(R.id.chat_page).setVisibility(
View.GONE);
visibleView.findViewById(R.id.chat_page).clearAnimation();
}
}
};
/**
* Whether pages are shown.
*/
private boolean pagesShown;
private final Handler handler;
public PageSwitcher(Context context, AttributeSet attrs) {
super(context, attrs);
touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
......@@ -188,12 +147,6 @@ public class PageSwitcher extends ViewGroup implements AnimationListener {
visiblePosition = 0;
visibleView = null;
previousVisibleObject = null;
handler = new Handler();
pagesHideAnimation = AnimationUtils.loadAnimation(context,
R.anim.chat_page_out);
pagesHideAnimation.setAnimationListener(this);
pagesShown = false;
}
/**
......@@ -529,11 +482,17 @@ public class PageSwitcher extends ViewGroup implements AnimationListener {
if (scrollX == 0) {
if (LOG)
LogManager.i(this, "Scroll X == 0");
hidePages();
if (visibleView != null)
adapter.hidePages(visibleView);
if (selectedView != null)
adapter.hidePages(selectedView);
} else {
if (LOG)
LogManager.i(this, "Scroll X != 0");
showPages();
if (visibleView != null)
adapter.showPages(visibleView);
if (selectedView != null)
adapter.showPages(selectedView);
}
super.scrollTo(scrollX, 0);
......@@ -541,36 +500,6 @@ public class PageSwitcher extends ViewGroup implements AnimationListener {
dataChanged = false;
}
/**
* Show pages.
*/
private void showPages() {
if (pagesShown)
return;
pagesShown = true;
handler.removeCallbacks(pagesHideRunnable);
if (selectedView != null) {
selectedView.findViewById(R.id.chat_page).clearAnimation();
selectedView.findViewById(R.id.chat_page).setVisibility(
View.VISIBLE);
}
if (visibleView != null) {
visibleView.findViewById(R.id.chat_page).clearAnimation();
visibleView.findViewById(R.id.chat_page)
.setVisibility(View.VISIBLE);
}
}
/**
* Requests pages to be hiden in future.
*/
private void hidePages() {
if (!pagesShown)
return;
pagesShown = false;
handler.postDelayed(pagesHideRunnable, PAGES_HIDDER_DELAY);
}
/**
* Save state of views. Must be called on activity pause.
*/
......@@ -739,20 +668,6 @@ public class PageSwitcher extends ViewGroup implements AnimationListener {
update(false);
}
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
if (selectedView != null)
selectedView.findViewById(R.id.chat_page).setVisibility(View.GONE);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
public interface OnSelectListener {
/**
......
......@@ -194,7 +194,12 @@ public class DummyCursor implements Cursor {
Uri paramUri) {
}
@Override
@Override
public Uri getNotificationUri() {
return null;
}
@Override
public boolean getWantsAllOnMoveCalls() {
return false;
}
......@@ -209,4 +214,9 @@ public class DummyCursor implements Cursor {
return null;
}
@Override
public int getType(int arg0) {
return 0;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment