Rework the de-duplication scheme for shortcuts.

Bug: 4646172
Change-Id: I88966f3e910f51711ce49336fb9134d0953930de
diff --git a/src/com/android/settings/UserDictionarySettings.java b/src/com/android/settings/UserDictionarySettings.java
index ec21111..822c490 100644
--- a/src/com/android/settings/UserDictionarySettings.java
+++ b/src/com/android/settings/UserDictionarySettings.java
@@ -67,7 +67,11 @@
     private static final String QUERY_SELECTION_ALL_LOCALES =
             UserDictionary.Words.LOCALE + " is null";
 
-    private static final String DELETE_SELECTION = UserDictionary.Words.WORD + "=?";
+    private static final String DELETE_SELECTION_WITH_SHORTCUT = UserDictionary.Words.WORD
+            + "=? AND " + UserDictionary.Words.SHORTCUT + "=?";
+    private static final String DELETE_SELECTION_WITHOUT_SHORTCUT = UserDictionary.Words.WORD
+            + "=? AND " + UserDictionary.Words.SHORTCUT + " is null OR "
+            + UserDictionary.Words.SHORTCUT + "=''";
 
     private static final int OPTIONS_MENU_ADD = Menu.FIRST;
 
@@ -220,9 +224,17 @@
                 mCursor.getColumnIndexOrThrow(UserDictionary.Words.SHORTCUT));
     }
 
-    public static void deleteWord(final String word, final ContentResolver resolver) {
-        resolver.delete(
-                UserDictionary.Words.CONTENT_URI, DELETE_SELECTION, new String[] { word });
+    public static void deleteWord(final String word, final String shortcut,
+            final ContentResolver resolver) {
+        if (TextUtils.isEmpty(shortcut)) {
+            resolver.delete(
+                    UserDictionary.Words.CONTENT_URI, DELETE_SELECTION_WITHOUT_SHORTCUT,
+                    new String[] { word });
+        } else {
+            resolver.delete(
+                    UserDictionary.Words.CONTENT_URI, DELETE_SELECTION_WITH_SHORTCUT,
+                    new String[] { word, shortcut });
+        }
     }
 
     private static class MyAdapter extends SimpleCursorAdapter implements SectionIndexer {
diff --git a/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java b/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java
index 95e031e..1e8bf74 100644
--- a/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java
+++ b/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java
@@ -90,22 +90,38 @@
     /* package */ void apply(final Context context) {
         final ContentResolver resolver = context.getContentResolver();
         if (UserDictionaryAddWordContents.MODE_EDIT == mMode && !TextUtils.isEmpty(mOldWord)) {
-            UserDictionarySettings.deleteWord(mOldWord, resolver);
+            // Mode edit: remove the old entry.
+            UserDictionarySettings.deleteWord(mOldWord, mOldShortcut, resolver);
         }
         final String newWord = mWordEditText.getText().toString();
+        final String newShortcut;
+        if (null == mShortcutEditText) {
+            newShortcut = null;
+        } else {
+            final String tmpShortcut = mShortcutEditText.getText().toString();
+            if (TextUtils.isEmpty(tmpShortcut)) {
+                newShortcut = null;
+            } else {
+                newShortcut = tmpShortcut;
+            }
+        }
         if (TextUtils.isEmpty(newWord)) {
             // If the word is somehow empty, don't insert it.
             return;
         }
-        // Disallow duplicates.
-        // TODO: Redefine the logic when we support shortcuts.
-        UserDictionarySettings.deleteWord(newWord, resolver);
+        // Disallow duplicates. If the same word with no shortcut is defined, remove it; if
+        // the same word with the same shortcut is defined, remove it; but we don't mind if
+        // there is the same word with a different, non-empty shortcut.
+        UserDictionarySettings.deleteWord(newWord, null, resolver);
+        if (!TextUtils.isEmpty(newShortcut)) {
+            // If newShortcut is empty we just deleted this, no need to do it again
+            UserDictionarySettings.deleteWord(newWord, newShortcut, resolver);
+        }
 
         // In this class we use the empty string to represent 'all locales' and mLocale cannot
         // be null. However the addWord method takes null to mean 'all locales'.
         UserDictionary.Words.addWord(context, newWord.toString(),
-                FREQUENCY_FOR_USER_DICTIONARY_ADDS,
-                null == mShortcutEditText ? null : mShortcutEditText.getText().toString(),
+                FREQUENCY_FOR_USER_DICTIONARY_ADDS, newShortcut,
                 TextUtils.isEmpty(mLocale) ? null : Utils.createLocaleFromString(mLocale));
     }