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      */
UserDictionaryToolsEdit()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      */
UserDictionaryToolsEdit(View focusView, View focusPairView)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      */
sendEventToIME(OpenWnnEvent ev)108     protected abstract boolean sendEventToIME(OpenWnnEvent ev);
109 
110     /** @see android.app.Activity#onCreate */
onCreate(Bundle savedInstanceState)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 */
onKeyDown(int keyCode, KeyEvent event)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      */
setAddButtonControl()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 */
onClick(View v)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      */
doSaveAction()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      */
doRevertAction()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      */
onCreateDialog(int id)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