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