diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 14:04:32 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 14:04:32 -0800 |
commit | a07a33aa5f2468f0b3d8433ed1379fc4bdfba77f (patch) | |
tree | e228265a62cb42bc94ba473c2e37ede0a6786e64 /src/com/android/im | |
parent | e9ebcf259bb3dcb9debe0d88db4938cdf3218b9d (diff) | |
download | IM-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.java | 38 | ||||
-rw-r--r-- | src/com/android/im/app/ContactView.java | 61 | ||||
-rw-r--r-- | src/com/android/im/app/FrontDoorPlugin.java | 124 | ||||
-rw-r--r-- | src/com/android/im/app/Ticker.java | 54 | ||||
-rw-r--r-- | src/com/android/im/app/UserPresenceView.java | 82 |
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); } } |