summaryrefslogtreecommitdiff
path: root/src/com/android/im
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 14:04:32 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 14:04:32 -0800
commita07a33aa5f2468f0b3d8433ed1379fc4bdfba77f (patch)
treee228265a62cb42bc94ba473c2e37ede0a6786e64 /src/com/android/im
parente9ebcf259bb3dcb9debe0d88db4938cdf3218b9d (diff)
downloadIM-a07a33aa5f2468f0b3d8433ed1379fc4bdfba77f.tar.gz
auto import from //depot/cupcake/@132589
Diffstat (limited to 'src/com/android/im')
-rw-r--r--src/com/android/im/app/ChatView.java38
-rw-r--r--src/com/android/im/app/ContactView.java61
-rw-r--r--src/com/android/im/app/FrontDoorPlugin.java124
-rw-r--r--src/com/android/im/app/Ticker.java54
-rw-r--r--src/com/android/im/app/UserPresenceView.java82
5 files changed, 173 insertions, 186 deletions
diff --git a/src/com/android/im/app/ChatView.java b/src/com/android/im/app/ChatView.java
index f3d0d34..bc1da91 100644
--- a/src/com/android/im/app/ChatView.java
+++ b/src/com/android/im/app/ChatView.java
@@ -348,27 +348,15 @@ public class ChatView extends LinearLayout {
case KeyEvent.KEYCODE_ENTER:
if (event.isAltPressed()) {
mEdtInput.append("\n");
- return true;
+ } else {
+ handleEnterKey();
}
+ return true;
}
}
return false;
}
});
-
- mEdtInput.setOnEditorActionListener(new TextView.OnEditorActionListener() {
- public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- if (event != null) {
- if (event.isAltPressed()) {
- return false;
- }
- }
-
- sendMessage();
- return true;
- }
- });
-
// TODO: this is a hack to implement BUG #1611278, when dispatchKeyEvent() works with
// the soft keyboard, we should remove this hack.
mEdtInput.addTextChangedListener(new TextWatcher() {
@@ -423,6 +411,26 @@ public class ChatView extends LinearLayout {
unregisterChatSessionListener();
}
+ private void handleEnterKey() {
+ Configuration config = getResources().getConfiguration();
+ if (config.orientation == config.ORIENTATION_LANDSCAPE) {
+ // in the landscape mode, we'll send the message if the user is using a physical
+ // keyboard. However, on the soft keyboard, we'll close the keyboard and put the
+ // focus on the Send button, in order to prevent accidental sending the message.
+ if (config.hardKeyboardHidden == config.HARDKEYBOARDHIDDEN_NO) {
+ sendMessage();
+ } else {
+ closeSoftKeyboard();
+ mSendButton.requestFocus();
+ }
+ } else {
+ // in the portrait mode, the user would always be using the soft keyboard, so pressing
+ // the Enter key would close the keyboard and puts the focus on the Send button.
+ closeSoftKeyboard();
+ mSendButton.requestFocus();
+ }
+ }
+
private void closeSoftKeyboard() {
InputMethodManager inputMethodManager =
(InputMethodManager)mApp.getSystemService(Context.INPUT_METHOD_SERVICE);
diff --git a/src/com/android/im/app/ContactView.java b/src/com/android/im/app/ContactView.java
index 38ee6cf..c5d807d 100644
--- a/src/com/android/im/app/ContactView.java
+++ b/src/com/android/im/app/ContactView.java
@@ -24,6 +24,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
+import android.os.Handler;
import android.provider.Im;
import android.text.Spannable;
import android.text.SpannableString;
@@ -33,6 +34,8 @@ import android.text.style.RelativeSizeSpan;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -78,8 +81,12 @@ public class ContactView extends LinearLayout {
private TextView mLine2;
private TextView mTimeStamp;
+ private Handler mHandler;
+ private boolean mLayoutDirty;
+
public ContactView(Context context, AttributeSet attrs) {
super(context, attrs);
+ mLayoutDirty = true;
}
@Override
@@ -91,6 +98,58 @@ public class ContactView extends LinearLayout {
mLine2 = (TextView) findViewById(R.id.line2);
mLine2.setCompoundDrawablePadding(5);
mTimeStamp = (TextView)findViewById(R.id.timestamp);
+
+ mHandler = new Handler();
+ }
+
+ @Override
+ public void setSelected(boolean selected) {
+ super.setSelected(selected);
+ if(selected) {
+ // While layout, the width of children is unknown, we have to start
+ // animation when layout is done.
+ if (mLayoutDirty) {
+ mHandler.post(new Runnable() {
+ public void run() {
+ startAnimationNow();
+ }
+ });
+ } else {
+ startAnimationNow();
+ }
+ } else {
+ mLine2.clearAnimation();
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ mLayoutDirty = false;
+ super.onLayout(changed, l, t, r, b);
+ }
+
+ @Override
+ public void requestLayout() {
+ super.requestLayout();
+ mLayoutDirty = true;
+ }
+
+ /*package*/ void startAnimationNow() {
+ View parent = (View)mLine2.getParent();
+ int width = mLine2.getWidth();
+
+ int parentWidth = parent.getWidth() - parent.getPaddingLeft()
+ - parent.getPaddingRight();
+ if(width > parentWidth) {
+ int fromXDelta = parentWidth;
+ int toXDelta = - width;
+ int duration = (fromXDelta - toXDelta) * 32;
+ Animation animation = new TranslateAnimation(fromXDelta, toXDelta, 0, 0);
+ animation.setDuration(duration);
+ animation.setRepeatMode(Animation.RESTART);
+ animation.setRepeatCount(Animation.INFINITE);
+ mLine2.startAnimation(animation);
+ }
}
public void bind(Cursor cursor, String underLineText, boolean scrolling) {
@@ -204,7 +263,7 @@ public class ContactView extends LinearLayout {
View contactInfoPanel = findViewById(R.id.contactInfo);
if (hasChat && showChatMsg) {
- contactInfoPanel.setBackgroundResource(R.drawable.bubble);
+ contactInfoPanel.setBackgroundResource(R.drawable.list_item_im_bubble);
mLine1.setTextColor(r.getColor(R.color.chat_contact));
} else {
contactInfoPanel.setBackgroundDrawable(null);
diff --git a/src/com/android/im/app/FrontDoorPlugin.java b/src/com/android/im/app/FrontDoorPlugin.java
index 51e686c..4ef7041 100644
--- a/src/com/android/im/app/FrontDoorPlugin.java
+++ b/src/com/android/im/app/FrontDoorPlugin.java
@@ -50,16 +50,6 @@ public class FrontDoorPlugin extends Service {
private final static String TAG = ImApp.LOG_TAG;
private final static boolean LOCAL_DEBUG = false;
- // database access constants for branding resource map cache table
- private final static String[] BRANDING_RESOURCE_MAP_CACHE_PROJECTION = {
- Im.BrandingResourceMapCache.PROVIDER_ID,
- Im.BrandingResourceMapCache.APP_RES_ID,
- Im.BrandingResourceMapCache.PLUGIN_RES_ID
- };
- private final static int BRANDING_RESOURCE_MAP_CACHE_PROVIDER_ID_COLUMN = 0;
- private final static int BRANDING_RESOURCE_MAP_CACHE_APP_RES_ID_COLUMN = 1;
- private final static int BRANDING_RESOURCE_MAP_CACHE_PLUGIN_RES_ID_COLUMN = 2;
-
private ArrayList<String> mProviderNames;
private HashMap<String, String> mPackageNames;
private HashMap<String, String> mClassNames;
@@ -68,18 +58,12 @@ public class FrontDoorPlugin extends Service {
@Override
public IBinder onBind(Intent intent) {
- // temporary provider ID<->Name mappings
- HashMap<String, Long> providerNameToId = new HashMap<String, Long>();
- HashMap<Long, String> providerIdToName = new HashMap<Long, String>();
-
- loadThirdPartyPlugins(providerNameToId, providerIdToName);
- loadBrandingResources(providerNameToId, providerIdToName);
-
+ loadThirdPartyPlugins();
+ loadBrandingResources();
return mBinder;
}
- private void loadThirdPartyPlugins(HashMap<String, Long> providerNameToId,
- HashMap<Long, String> providerIdToName) {
+ private void loadThirdPartyPlugins() {
mProviderNames = new ArrayList<String>();
mPackageNames = new HashMap<String, String>();
mClassNames = new HashMap<String, String>();
@@ -116,9 +100,7 @@ public class FrontDoorPlugin extends Service {
mClassNames.put(providerName, serviceInfo.name);
mSrcPaths.put(providerName, serviceInfo.applicationInfo.sourceDir);
- long providerId = updateProviderDb(providerName, providerFullName, signUpUrl);
- providerNameToId.put(providerName, providerId);
- providerIdToName.put(providerId, providerName);
+ updateProviderDb(providerName, providerFullName, signUpUrl);
}
}
@@ -169,102 +151,9 @@ public class FrontDoorPlugin extends Service {
return providerId;
}
- private void loadBrandingResources(HashMap<String, Long> providerNameToId,
- HashMap<Long, String> providerIdToName) {
+ private void loadBrandingResources() {
mBrandingResources = new HashMap<String, Map<Integer, Integer>>();
- if (loadBrandingResourcesFromCache(providerIdToName) <= 0) {
- Log.w(TAG, "Can't load from cache. Load from plugins...");
- loadBrandingResourcesFromPlugins();
- saveBrandingResourcesToCache(providerNameToId);
- }
- }
-
- /**
- * Try loading the branding resources from the database.
- * @param providerIdToName a map between provider ID and name.
- * @return 0 if the resources are not cached yet; otherwise the total count of res id
- * pairs.
- */
- private int loadBrandingResourcesFromCache(HashMap<Long, String> providerIdToName) {
- ContentResolver cr = getContentResolver();
- Cursor c = cr.query(
- Im.BrandingResourceMapCache.CONTENT_URI, /* URI */
- BRANDING_RESOURCE_MAP_CACHE_PROJECTION, /* projection */
- null, /* where */
- null, /* where args */
- null /* sort */);
-
- int count = 0;
- if (c != null) {
- try {
- while (c.moveToNext()) {
- long providerId = c.getLong(BRANDING_RESOURCE_MAP_CACHE_PROVIDER_ID_COLUMN);
- String provider = providerIdToName.get(providerId);
- if (TextUtils.isEmpty(provider)) {
- Log.e(TAG, "Empty provider name in branding resource map cache table.");
- continue;
- }
- int appResId = c.getInt(BRANDING_RESOURCE_MAP_CACHE_APP_RES_ID_COLUMN);
- int pluginResId = c.getInt(BRANDING_RESOURCE_MAP_CACHE_PLUGIN_RES_ID_COLUMN);
-
- Map<Integer, Integer> resMap = mBrandingResources.get(provider);
- if (resMap == null) {
- resMap = new HashMap<Integer, Integer>();
- mBrandingResources.put(provider, resMap);
- }
-
- resMap.put(appResId, pluginResId);
-
- count++;
- }
- } finally {
- c.close();
- }
- } else {
- Log.e(TAG, "Query of branding resource map cache table returns empty cursor");
- }
-
- return count;
- }
-
- /**
- * Cache the loaded branding resources in IM database table, so that we can use it
- * directly and save loading time.
- * @param providerNameToId a map between provider name and ID.
- */
- private void saveBrandingResourcesToCache(HashMap<String, Long> providerNameToId) {
- ContentResolver cr = getContentResolver();
-
- ArrayList<ContentValues> valuesList = new ArrayList<ContentValues>();
- for (String provider : mBrandingResources.keySet()) {
- long providerId = providerNameToId.get(provider);
-
- Map<Integer, Integer> resMap = mBrandingResources.get(provider);
- for (int appResId : resMap.keySet()) {
- int pluginResId = resMap.get(appResId);
-
- ContentValues values = new ContentValues();
- values.put(Im.BrandingResourceMapCache.PROVIDER_ID, providerId);
- values.put(Im.BrandingResourceMapCache.APP_RES_ID, appResId);
- values.put(Im.BrandingResourceMapCache.PLUGIN_RES_ID, pluginResId);
-
- valuesList.add(values);
- }
- }
-
- int size = valuesList.size();
- if (size > 0) {
- cr.bulkInsert(
- Im.BrandingResourceMapCache.CONTENT_URI,
- valuesList.toArray(new ContentValues[size]));
- }
- }
-
- /**
- * Load the branding resources from all plugin packages.
- */
- private void loadBrandingResourcesFromPlugins() {
for (String provider : mProviderNames) {
if (!mBrandingResources.containsKey(provider)) {
if (LOCAL_DEBUG) log("loadBrandingResources: load resource map for " + provider);
@@ -277,9 +166,6 @@ public class FrontDoorPlugin extends Service {
}
}
- /**
- * Load branding resources from one plugin package.
- */
private Map<Integer, Integer> loadBrandingResource(String className, String srcPath) {
Map retVal = null;
diff --git a/src/com/android/im/app/Ticker.java b/src/com/android/im/app/Ticker.java
new file mode 100644
index 0000000..53d1ae1
--- /dev/null
+++ b/src/com/android/im/app/Ticker.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007-2008 Esmertec AG.
+ * Copyright (C) 2007-2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.im.app;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+
+public class Ticker extends FrameLayout {
+
+ public Ticker(Context context) {
+ super(context);
+ }
+
+ public Ticker(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public Ticker(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected void measureChild(View child, int parentWidthMeasureSpec,
+ int parentHeightMeasureSpec) {
+ LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ int childWidthMeasureSpec;
+ int childHeightMeasureSpec;
+
+ // Let the child be as wide as it wants, regardless of our bounds
+ childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec, mPaddingLeft
+ + mPaddingRight, lp.width);
+
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+}
diff --git a/src/com/android/im/app/UserPresenceView.java b/src/com/android/im/app/UserPresenceView.java
index 1250600..d07a00d 100644
--- a/src/com/android/im/app/UserPresenceView.java
+++ b/src/com/android/im/app/UserPresenceView.java
@@ -20,7 +20,6 @@ import com.android.im.IImConnection;
import com.android.im.R;
import com.android.im.engine.ImErrorInfo;
import com.android.im.engine.Presence;
-import com.android.im.plugin.ImpsConfigNames;
import com.google.android.collect.Lists;
import android.app.Activity;
@@ -38,7 +37,6 @@ import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
-import android.widget.TextView;
import java.util.List;
@@ -47,7 +45,7 @@ public class UserPresenceView extends LinearLayout {
private ImageButton mStatusDialogButton;
// views of the popup window
- TextView mStatusBar;
+ EditText mStatusEditor;
private final SimpleAlertHandler mHandler;
@@ -55,7 +53,7 @@ public class UserPresenceView extends LinearLayout {
private long mProviderId;
Presence mPresence;
- private String mLastStatusText;
+ private String mLastStatusEditText;
final List<StatusItem> mStatusItems = Lists.newArrayList();
public UserPresenceView(Context context, AttributeSet attrs) {
@@ -68,11 +66,35 @@ public class UserPresenceView extends LinearLayout {
super.onFinishInflate();
mStatusDialogButton = (ImageButton)findViewById(R.id.statusDropDownButton);
+ mStatusEditor = (EditText)findViewById(R.id.statusEdit);
+
mStatusDialogButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
showStatusListDialog();
}
});
+
+ mStatusEditor.setOnKeyListener(new OnKeyListener() {
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ if (KeyEvent.ACTION_DOWN == event.getAction()) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_CENTER:
+ case KeyEvent.KEYCODE_ENTER:
+ updateStatusText();
+ return true;
+ }
+ }
+ return false;
+ }
+ });
+
+ mStatusEditor.setOnFocusChangeListener(new View.OnFocusChangeListener(){
+ public void onFocusChange(View v, boolean hasFocus) {
+ if (!hasFocus) {
+ updateStatusText();
+ }
+ }
+ });
}
private void showStatusListDialog() {
@@ -117,11 +139,11 @@ public class UserPresenceView extends LinearLayout {
}
void updateStatusText() {
- String newStatusText = mStatusBar.getText().toString();
+ String newStatusText = mStatusEditor.getText().toString();
if (TextUtils.isEmpty(newStatusText)) {
newStatusText = "";
}
- if (!newStatusText.equals(mLastStatusText)) {
+ if (!newStatusText.equals(mLastStatusEditText)) {
updatePresence(-1, newStatusText);
}
}
@@ -151,12 +173,8 @@ public class UserPresenceView extends LinearLayout {
if (TextUtils.isEmpty(statusText)) {
statusText = brandingRes.getString(PresenceUtils.getStatusStringRes(status));
}
- mLastStatusText = statusText;
-
- if (mStatusBar == null) {
- mStatusBar = initStatusBar(mProviderId);
- }
- mStatusBar.setText(statusText);
+ mStatusEditor.setText(statusText);
+ mLastStatusEditText = statusText;
// Disable the user to edit the custom status text because
// the AIM and MSN server don't support it now.
@@ -164,45 +182,7 @@ public class UserPresenceView extends LinearLayout {
String providerName = provider == null ? null : provider.mName;
if (Im.ProviderNames.AIM.equals(providerName)
|| Im.ProviderNames.MSN.equals(providerName)) {
- mStatusBar.setFocusable(false);
- }
- }
-
- private TextView initStatusBar(long providerId) {
- String value = Im.ProviderSettings.getStringValue(
- mContext.getContentResolver(), providerId,
- ImpsConfigNames.SUPPORT_USER_DEFINED_PRESENCE);
-
- if ("true".equalsIgnoreCase(value)) {
- EditText statusEdit = (EditText) findViewById(R.id.statusEdit);
- statusEdit.setVisibility(View.VISIBLE);
- statusEdit.setOnKeyListener(new OnKeyListener() {
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- if (KeyEvent.ACTION_DOWN == event.getAction()) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_CENTER:
- case KeyEvent.KEYCODE_ENTER:
- updateStatusText();
- return true;
- }
- }
- return false;
- }
- });
-
- statusEdit.setOnFocusChangeListener(new View.OnFocusChangeListener(){
- public void onFocusChange(View v, boolean hasFocus) {
- if (!hasFocus) {
- updateStatusText();
- }
- }
- });
-
- return statusEdit;
- } else {
- TextView statusView = (TextView) findViewById(R.id.statusView);
- statusView.setVisibility(View.VISIBLE);
- return statusView;
+ mStatusEditor.setFocusable(false);
}
}