View Javadoc

1   /***
2    *     Aedict - an EDICT browser for Android
3    Copyright (C) 2009 Martin Vysny
4    
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9    
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14  
15   You should have received a copy of the GNU General Public License
16   along with this program.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  package sk.baka.aedict;
19  
20  import java.util.List;
21  
22  import sk.baka.aedict.dict.KanjidicEntry;
23  import sk.baka.aedict.dict.TanakaSearchTask;
24  import sk.baka.aedict.kanji.KanjiUtils;
25  import sk.baka.aedict.kanji.Radicals;
26  import sk.baka.aedict.kanji.RomanizationEnum;
27  import sk.baka.aedict.util.Check;
28  import sk.baka.aedict.util.Constants;
29  import sk.baka.aedict.util.SearchClickListener;
30  import sk.baka.aedict.util.SearchUtils;
31  import sk.baka.aedict.util.ShowRomaji;
32  import sk.baka.aedict.util.SpanStringBuilder;
33  import sk.baka.autils.DialogUtils;
34  import android.content.Context;
35  import android.content.Intent;
36  import android.os.Bundle;
37  import android.text.method.LinkMovementMethod;
38  import android.util.Log;
39  import android.view.Menu;
40  import android.view.View;
41  import android.view.ViewGroup;
42  import android.view.Window;
43  import android.widget.TextView;
44  
45  /***
46   * Shows a detail of a single Kanji character.
47   * 
48   * @author Martin Vysny
49   */
50  public class KanjiDetailActivity extends AbstractActivity {
51  	static final String INTENTKEY_KANJIDIC_ENTRY = "entry";
52  
53  	/***
54  	 * Launches this activity.
55  	 * 
56  	 * @param activity
57  	 *            caller activity, not null.
58  	 * @param entry
59  	 *            show this entry, not null.
60  	 */
61  	public static void launch(final Context activity, final KanjidicEntry entry) {
62  		Check.checkNotNull("activity", activity);
63  		Check.checkNotNull("entry", entry);
64  		final Intent intent = new Intent(activity, KanjiDetailActivity.class);
65  		intent.putExtra(INTENTKEY_KANJIDIC_ENTRY, entry);
66  		activity.startActivity(intent);
67  	}
68  
69  	private ShowRomaji showRomaji;
70  	private KanjidicEntry entry;
71  
72  	@Override
73  	protected void onRestoreInstanceState(Bundle savedInstanceState) {
74  		showRomaji.loadState(savedInstanceState);
75  	}
76  
77  	@Override
78  	protected void onSaveInstanceState(Bundle outState) {
79  		showRomaji.saveState(outState);
80  	}
81  
82  	@Override
83  	protected void onCreate(Bundle savedInstanceState) {
84  		super.onCreate(savedInstanceState);
85  		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
86  		setContentView(R.layout.kanji_detail);
87  		showRomaji = new ShowRomaji() {
88  
89  			@Override
90  			protected void show(boolean romaji) {
91  				updateContent();
92  				tanakaSearchTask.updateModel();
93  			}
94  		};
95  		entry = (KanjidicEntry) getIntent().getSerializableExtra(INTENTKEY_KANJIDIC_ENTRY);
96  		MainActivity.recentlyViewed(entry);
97  		final TextView kanji = (TextView) findViewById(R.id.kanji);
98  		kanji.setText(entry.kanji);
99  		new SearchClickListener(this, entry.kanji).registerTo(kanji);
100 		((TextView) findViewById(R.id.stroke)).setText(Integer.toString(entry.strokes));
101 		((TextView) findViewById(R.id.grade)).setText(entry.grade == null ? "-" : entry.grade.toString());
102 		((TextView) findViewById(R.id.skip)).setText(entry.skip);
103 		final Integer jlpt = entry.getJlpt();
104 		((TextView) findViewById(R.id.jlpt)).setText(jlpt == null ? "-" : jlpt.toString());
105 		((TextView) findViewById(R.id.radicals)).setText(Radicals.getRadicals(entry.getKanji()));
106 		((TextView) findViewById(R.id.radicalNumber)).setText(String.valueOf(entry.radical));
107 		final SearchUtils utils = new SearchUtils(this);
108 		utils.setupCopyButton(R.id.copy, R.id.kanji);
109 		findViewById(R.id.showStrokeOrder).setOnClickListener(new View.OnClickListener() {
110 
111 			public void onClick(View v) {
112 				StrokeOrderActivity.launch(KanjiDetailActivity.this, entry.kanji);
113 			}
114 		});
115 		findViewById(R.id.showRadical).setOnClickListener(new View.OnClickListener() {
116 
117 			public void onClick(View v) {
118 				KanjiAnalyzeActivity.launch(KanjiDetailActivity.this, Radicals.getRadicals(entry.getKanji()), false);
119 			}
120 		});
121 		findViewById(R.id.addToNotepad).setOnClickListener(new View.OnClickListener() {
122 
123 			public void onClick(View v) {
124 				NotepadActivity.addAndLaunch(KanjiDetailActivity.this, entry);
125 			}
126 		});
127 		addTextViews(R.id.english, null, entry.getEnglish(), false);
128 		updateContent();
129 		// display hint
130 		if (!AedictApp.isInstrumentation) {
131 			new DialogUtils(this).showInfoOnce(Constants.INFOONCE_CLICKABLE_NOTE, R.string.note, R.string.clickableNote);
132 		}
133 	}
134 
135 	private void updateContent() {
136 		// compute ONYOMI, KUNYOMI, NAMAE and ENGLISH
137 		addTextViews(R.id.onyomi, "Onyomi: ", entry.getOnyomi(), true);
138 		addTextViews(R.id.kunyomi, "Kunyomi: ", entry.getKunyomi(), true);
139 		addTextViews(R.id.namae, "Namae: ", entry.getNamae(), true);
140 	}
141 
142 	private void addTextViews(final int parent, final String name, final List<String> items, final boolean isJapanese) {
143 		final TextView p = (TextView) findViewById(parent);
144 		p.setVisibility(items.isEmpty() ? View.GONE : View.VISIBLE);
145 		p.setMovementMethod(new LinkMovementMethod());
146 		final SpanStringBuilder sb = new SpanStringBuilder();
147 		if (name != null) {
148 			sb.append(sb.newSize(this, 15), name);
149 		}
150 		for (int i = 0; i < items.size(); i++) {
151 			String item = items.get(i);
152 			final String sitem = KanjidicEntry.removeSplits(item);
153 			if (sitem.trim().length() == 0) {
154 				continue;
155 			}
156 			if (isJapanese) {
157 				item = showRomaji.romanize(item);
158 			}
159 			String query = KanjiUtils.isKatakana(sitem.charAt(0)) ? RomanizationEnum.NihonShiki.toHiragana(RomanizationEnum.NihonShiki.toRomaji(sitem)) : sitem;
160 			if (isJapanese) {
161 				query += " AND " + entry.kanji;
162 			}
163 			final Object span = sb.newClickable(new SearchClickListener(this, query));
164 			sb.append(span, item);
165 			if (i < items.size() - 1) {
166 				sb.append(", ");
167 			}
168 		}
169 		p.setText(sb);
170 	}
171 
172 	@Override
173 	public boolean onPrepareOptionsMenu(Menu menu) {
174 		showRomaji.register(this, menu);
175 		AbstractActivity.addMenuItems(this, menu);
176 		return true;
177 	}
178 
179 	private TanakaSearchTask tanakaSearchTask;
180 
181 	@Override
182 	protected void onResume() {
183 		super.onResume();
184 		if (tanakaSearchTask == null && entry.isValid()) {
185 			tanakaSearchTask = new TanakaSearchTask(this, (ViewGroup) findViewById(R.id.tanakaExamples), showRomaji, entry.getJapanese());
186 			tanakaSearchTask.execute(entry.getJapanese());
187 		}
188 		// the tanakaSearchTask must be non-null otherwise this will fail.
189 		showRomaji.onResume();
190 	}
191 
192 	@Override
193 	protected void onStop() {
194 		if (tanakaSearchTask.cancel(true)) {
195 			tanakaSearchTask = null;
196 		}
197 		super.onStop();
198 	}
199 
200 }