Home | History | Annotate | Download | only in openwnn
      1 /*
      2  * Copyright (C) 2008-2012  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         setContentView(R.layout.user_dictionary_tools_edit);
    117 
    118         /* get widgets */
    119         mEntryButton = (Button)findViewById(R.id.addButton);
    120         mCancelButton = (Button)findViewById(R.id.cancelButton);
    121         mReadEditText = (EditText)findViewById(R.id.editRead);
    122         mCandidateEditText = (EditText)findViewById(R.id.editCandidate);
    123 
    124         /* set the listener */
    125         mEntryButton.setOnClickListener(this);
    126         mCancelButton.setOnClickListener(this);
    127 
    128         /* initialize */
    129         mRequestState = STATE_UNKNOWN;
    130         mReadEditText.setSingleLine();
    131         mCandidateEditText.setSingleLine();
    132 
    133         /* get the request and do it */
    134         Intent intent = getIntent();
    135         String action = intent.getAction();
    136         if (action.equals(Intent.ACTION_INSERT)) {
    137             /* add a word */
    138             mEntryButton.setEnabled(false);
    139             mRequestState = STATE_INSERT;
    140         } else if (action.equals(Intent.ACTION_EDIT)) {
    141             /* edit a word */
    142             mEntryButton.setEnabled(true);
    143             mReadEditText.setText(((TextView)sFocusingView).getText());
    144             mCandidateEditText.setText(((TextView)sFocusingPairView).getText());
    145             mRequestState = STATE_EDIT;
    146 
    147             /* save the word's information before this edit */
    148             mBeforeEditWnnWord = new WnnWord();
    149             mBeforeEditWnnWord.stroke = ((TextView)sFocusingView).getText().toString();
    150             mBeforeEditWnnWord.candidate = ((TextView)sFocusingPairView).getText().toString();
    151         } else {
    152             /* finish if it is unknown request */
    153             Log.e("OpenWnn", "onCreate() : Invaled Get Intent. ID=" + intent);
    154             finish();
    155             return;
    156         }
    157 
    158         getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
    159                                   R.layout.user_dictionary_tools_edit_header);
    160 
    161         /* set control buttons */
    162         setAddButtonControl();
    163 
    164     }
    165 
    166     /** @see android.app.Activity#onKeyDown */
    167     @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
    168         if (keyCode == KeyEvent.KEYCODE_BACK) {
    169             /* go back to the word list view */
    170             screenTransition();
    171             return true;
    172         }
    173         return super.onKeyDown(keyCode, event);
    174     }
    175 
    176     /**
    177      * Change the state of the "Add" button into the depending state of input area.
    178      */
    179     public void setAddButtonControl() {
    180 
    181         /* Text changed listener for the reading text */
    182         mReadEditText.addTextChangedListener(new TextWatcher() {
    183             public void afterTextChanged(Editable s) {
    184             }
    185             public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    186             }
    187             public void onTextChanged(CharSequence s, int start, int before, int count) {
    188                 /* Enable/disable the "Add" button */
    189                 if ((mReadEditText.getText().toString().length() != 0) &&
    190                     (mCandidateEditText.getText().toString().length() != 0)) {
    191                     mEntryButton.setEnabled(true);
    192                 } else {
    193                     mEntryButton.setEnabled(false);
    194                 }
    195             }
    196         });
    197         /* Text changed listener for the candidate text */
    198         mCandidateEditText.addTextChangedListener(new TextWatcher() {
    199             public void afterTextChanged(Editable s) {
    200             }
    201             public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    202             }
    203             public void onTextChanged(CharSequence s, int start, int before, int count) {
    204             	/* Enable/disable the "Add" button */
    205                 if ((mReadEditText.getText().toString().length() != 0) &&
    206                     (mCandidateEditText.getText().toString().length() != 0)) {
    207                     mEntryButton.setEnabled(true);
    208                 } else {
    209                     mEntryButton.setEnabled(false);
    210                 }
    211             }
    212         });
    213 
    214     }
    215 
    216     /** @see android.view.View.OnClickListener */
    217     public void onClick(View v) {
    218 
    219         mEntryButton.setEnabled(false);
    220         mCancelButton.setEnabled(false);
    221 
    222         switch (v.getId()) {
    223             case R.id.addButton:
    224                 /* save the word */
    225                 doSaveAction();
    226                 break;
    227 
    228             case R.id.cancelButton:
    229                 /* cancel the edit */
    230                 doRevertAction();
    231                 break;
    232 
    233             default:
    234                 Log.e("OpenWnn", "onClick: Get Invalid ButtonID. ID=" + v.getId());
    235                 finish();
    236                 return;
    237         }
    238     }
    239 
    240     /**
    241      * Process the adding or editing action
    242      */
    243     private void doSaveAction() {
    244 
    245         switch (mRequestState) {
    246         case STATE_INSERT:
    247             /* register a word */
    248             if (inputDataCheck(mReadEditText) && inputDataCheck(mCandidateEditText)) {
    249                     String stroke = mReadEditText.getText().toString();
    250                     String candidate = mCandidateEditText.getText().toString();
    251                     if (addDictionary(stroke, candidate)) {
    252                         screenTransition();
    253                     }
    254                 }
    255             break;
    256 
    257         case STATE_EDIT:
    258             /* edit a word (=delete the word selected & add the word edited) */
    259             if (inputDataCheck(mReadEditText) && inputDataCheck(mCandidateEditText)) {
    260                 deleteDictionary(mBeforeEditWnnWord);
    261                     String stroke = mReadEditText.getText().toString();
    262                     String candidate = mCandidateEditText.getText().toString();
    263                     if (addDictionary(stroke, candidate)) {
    264                         screenTransition();
    265                     } else {
    266                         addDictionary(mBeforeEditWnnWord.stroke, mBeforeEditWnnWord.candidate);
    267                     }
    268                 }
    269             break;
    270 
    271         default:
    272             Log.e("OpenWnn", "doSaveAction: Invalid Add Status. Status=" + mRequestState);
    273             break;
    274         }
    275     }
    276 
    277     /**
    278      * Process the cancel action
    279      */
    280     private void doRevertAction() {
    281         /* go back to the words list */
    282         screenTransition();
    283     }
    284 
    285     /**
    286      * Create the alert dialog for notifying the error
    287      *
    288      * @param  id        The dialog ID
    289      * @return           The information of the dialog
    290      */
    291     @Override protected Dialog onCreateDialog(int id) {
    292         switch (id) {
    293             case DIALOG_CONTROL_WORDS_DUPLICATE:
    294                 /* there is the same word in the dictionary */
    295                 return new AlertDialog.Builder(UserDictionaryToolsEdit.this)
    296                         .setIcon(android.R.drawable.ic_dialog_alert)
    297                         .setMessage(R.string.user_dictionary_words_duplication_message)
    298                         .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
    299                             public void onClick(DialogInterface dialog, int whichButton) {
    300                                 mEntryButton.setEnabled(true);
    301                                 mCancelButton.setEnabled(true);
    302                             }
    303                         })
    304                         .setCancelable(true)
    305                         .setOnCancelListener(new DialogInterface.OnCancelListener() {
    306                             public void onCancel(DialogInterface dialog) {
    307                                 mEntryButton.setEnabled(true);
    308                                 mCancelButton.setEnabled(true);
    309                             }
    310                         })
    311                         .create();
    312 
    313             case DIALOG_CONTROL_OVER_MAX_TEXT_SIZE:
    314                 /* the length of the word exceeds the limit */
    315                 return new AlertDialog.Builder(UserDictionaryToolsEdit.this)
    316                         .setIcon(android.R.drawable.ic_dialog_alert)
    317                         .setMessage(R.string.user_dictionary_over_max_text_size_message)
    318                         .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
    319                             public void onClick(DialogInterface dialog, int witchButton) {
    320                                 mEntryButton.setEnabled(true);
    321                                 mCancelButton.setEnabled(true);
    322                             }
    323                         })
    324                         .setCancelable(true)
    325                         .create();
    326         }
    327         return super.onCreateDialog(id);
    328     }
    329 
    330     /**
    331      * Add the word
    332      *
    333      * @param  stroke       The stroke of the word
    334      * @param  candidate    The string of the word
    335      * @return              {@code true} if success; {@code false} if fail.
    336      */
    337     private boolean addDictionary(String stroke, String candidate) {
    338         boolean ret;
    339 
    340         /* create WnnWord from the strings */
    341         WnnWord wnnWordAdd = new WnnWord();
    342         wnnWordAdd.stroke = stroke;
    343         wnnWordAdd.candidate = candidate;
    344         /* add word event */
    345         OpenWnnEvent event = new OpenWnnEvent(OpenWnnEvent.ADD_WORD,
    346                                   WnnEngine.DICTIONARY_TYPE_USER,
    347                                   wnnWordAdd);
    348         /* notify the event to IME */
    349         ret = sendEventToIME(event);
    350         if (ret == false) {
    351             /* get error code if the process in IME is failed */
    352             int ret_code = event.errorCode;
    353             if (ret_code == RETURN_SAME_WORD) {
    354                 showDialog(DIALOG_CONTROL_WORDS_DUPLICATE);
    355             }
    356         } else {
    357             /* update the dictionary */
    358             mListInstance = createUserDictionaryToolsList();
    359         }
    360         return ret;
    361     }
    362 
    363     /**
    364      * Delete the word
    365      *
    366      * @param  word     The information of word
    367      */
    368     private void deleteDictionary(WnnWord word) {
    369         /* delete the word from the dictionary */
    370         mListInstance = createUserDictionaryToolsList();
    371         boolean deleted = mListInstance.deleteWord(word);
    372         if (!deleted) {
    373             Toast.makeText(getApplicationContext(),
    374                            R.string.user_dictionary_delete_fail,
    375                            Toast.LENGTH_LONG).show();
    376         }
    377     }
    378 
    379     /**
    380      * Create the instance of UserDictionaryToolList object
    381      */
    382     protected abstract UserDictionaryToolsList createUserDictionaryToolsList();
    383 
    384     /**
    385      * Check the input string
    386      *
    387      * @param   v       The information of view
    388      * @return          {@code true} if success; {@code false} if fail.
    389      */
    390     private boolean inputDataCheck(View v) {
    391 
    392         /* return false if the length of the string exceeds the limit. */
    393         if ((((TextView)v).getText().length()) > MAX_TEXT_SIZE) {
    394             showDialog(DIALOG_CONTROL_OVER_MAX_TEXT_SIZE);
    395             Log.e("OpenWnn", "inputDataCheck() : over max string length.");
    396             return false;
    397         }
    398 
    399         return true;
    400     }
    401 
    402     /**
    403      * Transit the new state
    404      */
    405     private void screenTransition() {
    406         finish();
    407 
    408         /* change to the word listing window */
    409         Intent intent = new Intent();
    410         intent.setClassName(mPackageName, mListViewName);
    411         startActivity(intent);
    412 
    413     }
    414 
    415 }
    416