Home | History | Annotate | Download | only in openwnn
      1 /*
      2  * Copyright (C) 2008,2009  OMRON SOFTWARE Co., Ltd.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package jp.co.omronsoft.openwnn;
     18 
     19 import android.app.Activity;
     20 import android.app.AlertDialog;
     21 import android.app.Dialog;
     22 import android.content.DialogInterface;
     23 import android.content.Intent;
     24 import android.os.Bundle;
     25 import android.text.Editable;
     26 import android.text.TextWatcher;
     27 import android.util.Log;
     28 import android.view.KeyEvent;
     29 import android.view.View;
     30 import android.view.Window;
     31 import android.widget.Button;
     32 import android.widget.EditText;
     33 import android.widget.TextView;
     34 import android.widget.Toast;
     35 
     36 /**
     37  * The abstract class for user dictionary's word editor.
     38  *
     39  * @author Copyright (C) 2009, OMRON SOFTWARE CO., LTD.  All Rights Reserved.
     40  */
     41 public abstract class UserDictionaryToolsEdit extends Activity implements View.OnClickListener {
     42     /** The class information for intent(Set this informations in the extend class) */
     43     protected String  mListViewName;
     44     /** The class information for intent(Set this informations in the extend class) */
     45     protected String  mPackageName;
     46 
     47     /** The operation mode (Unknown) */
     48     private static final int STATE_UNKNOWN = 0;
     49     /** The operation mode (Add the word) */
     50     private static final int STATE_INSERT = 1;
     51     /** The operation mode (Edit the word) */
     52     private static final int STATE_EDIT = 2;
     53 
     54     /** Maximum length of a word's string */
     55     private static final int MAX_TEXT_SIZE = 20;
     56 
     57     /** The error code (Already registered the same word) */
     58     private static final int RETURN_SAME_WORD = -11;
     59 
     60     /** The focus view and pair view */
     61     private static View sFocusingView = null;
     62     private static View sFocusingPairView = null;
     63 
     64     /** Widgets which constitute this screen of activity */
     65     private EditText mReadEditText;
     66     private EditText mCandidateEditText;
     67     private Button mEntryButton;
     68     private Button mCancelButton;
     69 
     70     /** The word information which contains the previous information */
     71     private WnnWord mBeforeEditWnnWord;
     72     /** The instance of word list activity */
     73     private UserDictionaryToolsList mListInstance;
     74 
     75     /** The constant for notifying dialog (Already exists the specified word) */
     76     private static final int DIALOG_CONTROL_WORDS_DUPLICATE = 0;
     77     /** The constant for notifying dialog (The length of specified stroke or candidate exceeds the limit) */
     78     private static final int DIALOG_CONTROL_OVER_MAX_TEXT_SIZE = 1;
     79 
     80     /** The operation mode of this activity */
     81     private int mRequestState;
     82 
     83     /**
     84      * Constructor
     85      */
     86     public UserDictionaryToolsEdit() {
     87         super();
     88     }
     89 
     90     /**
     91      * Constructor
     92      *
     93      * @param  focusView      The information of view
     94      * @param  focusPairView  The information of pair of view
     95      */
     96     public UserDictionaryToolsEdit(View focusView, View focusPairView) {
     97         super();
     98         sFocusingView = focusView;
     99         sFocusingPairView = focusPairView;
    100     }
    101 
    102     /**
    103      * Send the specified event to IME
    104      *
    105      * @param ev    The event object
    106      * @return      {@code true} if this event is processed.
    107      */
    108     protected abstract boolean sendEventToIME(OpenWnnEvent ev);
    109 
    110     /** @see android.app.Activity#onCreate */
    111     @Override protected void onCreate(Bundle savedInstanceState) {
    112 
    113         super.onCreate(savedInstanceState);
    114 
    115         /* create view from XML layout */
    116         requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
    117         setContentView(R.layout.user_dictionary_tools_edit);
    118 
    119         /* get widgets */
    120         mEntryButton = (Button)findViewById(R.id.addButton);
    121         mCancelButton = (Button)findViewById(R.id.cancelButton);
    122         mReadEditText = (EditText)findViewById(R.id.editRead);
    123         mCandidateEditText = (EditText)findViewById(R.id.editCandidate);
    124 
    125         /* set the listener */
    126         mEntryButton.setOnClickListener(this);
    127         mCancelButton.setOnClickListener(this);
    128 
    129         /* initialize */
    130         mRequestState = STATE_UNKNOWN;
    131         mReadEditText.setSingleLine();
    132         mCandidateEditText.setSingleLine();
    133 
    134         /* get the request and do it */
    135         Intent intent = getIntent();
    136         String action = intent.getAction();
    137         if (action.equals(Intent.ACTION_INSERT)) {
    138             /* add a word */
    139             mEntryButton.setEnabled(false);
    140             mRequestState = STATE_INSERT;
    141         } else if (action.equals(Intent.ACTION_EDIT)) {
    142             /* edit a word */
    143             mEntryButton.setEnabled(true);
    144             mReadEditText.setText(((TextView)sFocusingView).getText());
    145             mCandidateEditText.setText(((TextView)sFocusingPairView).getText());
    146             mRequestState = STATE_EDIT;
    147 
    148             /* save the word's information before this edit */
    149             mBeforeEditWnnWord = new WnnWord();
    150             mBeforeEditWnnWord.stroke = ((TextView)sFocusingView).getText().toString();
    151             mBeforeEditWnnWord.candidate = ((TextView)sFocusingPairView).getText().toString();
    152         } else {
    153             /* finish if it is unknown request */
    154             Log.e("OpenWnn", "onCreate() : Invaled Get Intent. ID=" + intent);
    155             finish();
    156             return;
    157         }
    158 
    159         getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
    160                                   R.layout.user_dictionary_tools_edit_header);
    161 
    162         /* set control buttons */
    163         setAddButtonControl();
    164 
    165     }
    166 
    167     /** @see android.app.Activity#onKeyDown */
    168     @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
    169         if (keyCode == KeyEvent.KEYCODE_BACK) {
    170             /* go back to the word list view */
    171             screenTransition();
    172             return true;
    173         }
    174         return super.onKeyDown(keyCode, event);
    175     }
    176 
    177     /**
    178      * Change the state of the "Add" button into the depending state of input area.
    179      */
    180     public void setAddButtonControl() {
    181 
    182         /* Text changed listener for the reading text */
    183         mReadEditText.addTextChangedListener(new TextWatcher() {
    184             public void afterTextChanged(Editable s) {
    185             }
    186             public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    187             }
    188             public void onTextChanged(CharSequence s, int start, int before, int count) {
    189                 /* Enable/disable the "Add" button */
    190                 if ((mReadEditText.getText().toString().length() != 0) &&
    191                     (mCandidateEditText.getText().toString().length() != 0)) {
    192                     mEntryButton.setEnabled(true);
    193                 } else {
    194                     mEntryButton.setEnabled(false);
    195                 }
    196             }
    197         });
    198         /* Text changed listener for the candidate text */
    199         mCandidateEditText.addTextChangedListener(new TextWatcher() {
    200             public void afterTextChanged(Editable s) {
    201             }
    202             public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    203             }
    204             public void onTextChanged(CharSequence s, int start, int before, int count) {
    205             	/* Enable/disable the "Add" button */
    206                 if ((mReadEditText.getText().toString().length() != 0) &&
    207                     (mCandidateEditText.getText().toString().length() != 0)) {
    208                     mEntryButton.setEnabled(true);
    209                 } else {
    210                     mEntryButton.setEnabled(false);
    211                 }
    212             }
    213         });
    214 
    215     }
    216 
    217     /** @see android.view.View.OnClickListener */
    218     public void onClick(View v) {
    219 
    220         mEntryButton.setEnabled(false);
    221         mCancelButton.setEnabled(false);
    222 
    223         switch (v.getId()) {
    224             case R.id.addButton:
    225                 /* save the word */
    226                 doSaveAction();
    227                 break;
    228 
    229             case R.id.cancelButton:
    230                 /* cancel the edit */
    231                 doRevertAction();
    232                 break;
    233 
    234             default:
    235                 Log.e("OpenWnn", "onClick: Get Invalid ButtonID. ID=" + v.getId());
    236                 finish();
    237                 return;
    238         }
    239     }
    240 
    241     /**
    242      * Process the adding or editing action
    243      */
    244     private void doSaveAction() {
    245 
    246         switch (mRequestState) {
    247         case STATE_INSERT:
    248             /* register a word */
    249             if (inputDataCheck(mReadEditText) && inputDataCheck(mCandidateEditText)) {
    250                     String stroke = mReadEditText.getText().toString();
    251                     String candidate = mCandidateEditText.getText().toString();
    252                     if (addDictionary(stroke, candidate)) {
    253                         screenTransition();
    254                     }
    255                 }
    256             break;
    257 
    258         case STATE_EDIT:
    259             /* edit a word (=delete the word selected & add the word edited) */
    260             if (inputDataCheck(mReadEditText) && inputDataCheck(mCandidateEditText)) {
    261                 deleteDictionary(mBeforeEditWnnWord);
    262                     String stroke = mReadEditText.getText().toString();
    263                     String candidate = mCandidateEditText.getText().toString();
    264                     if (addDictionary(stroke, candidate)) {
    265                         screenTransition();
    266                     } else {
    267                         addDictionary(mBeforeEditWnnWord.stroke, mBeforeEditWnnWord.candidate);
    268                     }
    269                 }
    270             break;
    271 
    272         default:
    273             Log.e("OpenWnn", "doSaveAction: Invalid Add Status. Status=" + mRequestState);
    274             break;
    275         }
    276     }
    277 
    278     /**
    279      * Process the cancel action
    280      */
    281     private void doRevertAction() {
    282         /* go back to the words list */
    283         screenTransition();
    284     }
    285 
    286     /**
    287      * Create the alert dialog for notifying the error
    288      *
    289      * @param  id        The dialog ID
    290      * @return           The information of the dialog
    291      */
    292     @Override protected Dialog onCreateDialog(int id) {
    293         switch (id) {
    294             case DIALOG_CONTROL_WORDS_DUPLICATE:
    295                 /* there is the same word in the dictionary */
    296                 return new AlertDialog.Builder(UserDictionaryToolsEdit.this)
    297                         .setIcon(android.R.drawable.ic_dialog_alert)
    298                         .setMessage(R.string.user_dictionary_words_duplication_message)
    299                         .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
    300                             public void onClick(DialogInterface dialog, int whichButton) {
    301                                 mEntryButton.setEnabled(true);
    302                                 mCancelButton.setEnabled(true);
    303                             }
    304                         })
    305                         .setCancelable(true)
    306                         .setOnCancelListener(new DialogInterface.OnCancelListener() {
    307                             public void onCancel(DialogInterface dialog) {
    308                                 mEntryButton.setEnabled(true);
    309                                 mCancelButton.setEnabled(true);
    310                             }
    311                         })
    312                         .create();
    313 
    314             case DIALOG_CONTROL_OVER_MAX_TEXT_SIZE:
    315                 /* the length of the word exceeds the limit */
    316                 return new AlertDialog.Builder(UserDictionaryToolsEdit.this)
    317                         .setIcon(android.R.drawable.ic_dialog_alert)
    318                         .setMessage(R.string.user_dictionary_over_max_text_size_message)
    319                         .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
    320                             public void onClick(DialogInterface dialog, int witchButton) {
    321                                 mEntryButton.setEnabled(true);
    322                                 mCancelButton.setEnabled(true);
    323                             }
    324                         })
    325                         .setCancelable(true)
    326                         .create();
    327         }
    328         return super.onCreateDialog(id);
    329     }
    330 
    331     /**
    332      * Add the word
    333      *
    334      * @param  stroke       The stroke of the word
    335      * @param  candidate    The string of the word
    336      * @return              {@code true} if success; {@code false} if fail.
    337      */
    338     private boolean addDictionary(String stroke, String candidate) {
    339         boolean ret;
    340 
    341         /* create WnnWord from the strings */
    342         WnnWord wnnWordAdd = new WnnWord();
    343         wnnWordAdd.stroke = stroke;
    344         wnnWordAdd.candidate = candidate;
    345         /* add word event */
    346         OpenWnnEvent event = new OpenWnnEvent(OpenWnnEvent.ADD_WORD,
    347                                   WnnEngine.DICTIONARY_TYPE_USER,
    348                                   wnnWordAdd);
    349         /* notify the event to IME */
    350         ret = sendEventToIME(event);
    351         if (ret == false) {
    352             /* get error code if the process in IME is failed */
    353             int ret_code = event.errorCode;
    354             if (ret_code == RETURN_SAME_WORD) {
    355                 showDialog(DIALOG_CONTROL_WORDS_DUPLICATE);
    356             }
    357         } else {
    358             /* update the dictionary */
    359             mListInstance = createUserDictionaryToolsList();
    360         }
    361         return ret;
    362     }
    363 
    364     /**
    365      * Delete the word
    366      *
    367      * @param  word     The information of word
    368      */
    369     private void deleteDictionary(WnnWord word) {
    370         /* delete the word from the dictionary */
    371         mListInstance = createUserDictionaryToolsList();
    372         boolean deleted = mListInstance.deleteWord(word);
    373         if (!deleted) {
    374             Toast.makeText(getApplicationContext(),
    375                            R.string.user_dictionary_delete_fail,
    376                            Toast.LENGTH_LONG).show();
    377         }
    378     }
    379 
    380     /**
    381      * Create the instance of UserDictionaryToolList object
    382      */
    383     protected abstract UserDictionaryToolsList createUserDictionaryToolsList();
    384 
    385     /**
    386      * Check the input string
    387      *
    388      * @param   v       The information of view
    389      * @return          {@code true} if success; {@code false} if fail.
    390      */
    391     private boolean inputDataCheck(View v) {
    392 
    393         /* return false if the length of the string exceeds the limit. */
    394         if ((((TextView)v).getText().length()) > MAX_TEXT_SIZE) {
    395             showDialog(DIALOG_CONTROL_OVER_MAX_TEXT_SIZE);
    396             Log.e("OpenWnn", "inputDataCheck() : over max string length.");
    397             return false;
    398         }
    399 
    400         return true;
    401     }
    402 
    403     /**
    404      * Transit the new state
    405      */
    406     private void screenTransition() {
    407         finish();
    408 
    409         /* change to the word listing window */
    410         Intent intent = new Intent();
    411         intent.setClassName(mPackageName, mListViewName);
    412         startActivity(intent);
    413 
    414     }
    415 
    416 }
    417