now this is a working version of the app with topic disambiguation but it is still not optimal

This commit is contained in:
krasimir
2015-12-02 20:47:54 +00:00
parent f2b057c078
commit 967b87d9d3
11 changed files with 535 additions and 75 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

View File

@@ -4,49 +4,66 @@
android:layout_height="match_parent"
android:layout_width="match_parent">
<RelativeLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<RelativeLayout
android:id="@+id/lexical_header"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:padding="8dp"
android:background="#C0C0C0">
android:layout_height="match_parent"
android:layout_width="match_parent">
<org.grammaticalframework.ui.android.LanguageSelector
android:id="@+id/show_language"
<RelativeLayout
android:id="@+id/lexical_header"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:padding="0dp"/>
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:padding="8dp"
android:background="#C0C0C0">
<org.grammaticalframework.ui.android.LanguageSelector
android:id="@+id/show_language"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:padding="0dp"/>
</RelativeLayout>
<TextView
android:id="@+id/lexical_desc"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/lexical_header"
android:paddingLeft="1dp"
android:paddingTop="4dp"
android:paddingBottom="2dp"
android:textSize="25sp"/>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/lexical_desc"
android:orientation="vertical"
android:paddingLeft="1dp"
android:id="@android:id/list" >
</ListView>
</RelativeLayout>
<TextView
android:id="@+id/lexical_desc"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/lexical_header"
android:paddingLeft="1dp"
android:paddingTop="4dp"
android:paddingBottom="2dp"
android:textSize="25sp"/>
<ListView
android:layout_width="match_parent"
<!-- The navigation drawer -->
<ListView android:id="@+id/topics_list"
android:layout_width="250dp"
android:layout_height="match_parent"
android:layout_below="@id/lexical_desc"
android:orientation="vertical"
android:paddingLeft="1dp"
android:id="@android:id/list" >
</ListView>
</RelativeLayout>
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#FFFFE0"/>
</android.support.v4.widget.DrawerLayout>
<LinearLayout
android:id="@+id/progressBarView"
@@ -60,4 +77,4 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</FrameLayout>
</FrameLayout>

View File

@@ -18,10 +18,10 @@
android:layout_toRightOf="@id/arrow"
android:paddingLeft="10dp"
android:textSize="25sp"/>
<WebView
android:id="@+id/desc_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/lexical_desc"/>
</RelativeLayout>
</RelativeLayout>

View File

@@ -1,6 +1,8 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/input_mode"
android:title="@string/keyboard_input"/>
<item android:id="@+id/topics"
android:title="@string/topics"/>
<item android:id="@+id/help"
android:title="@string/help"/>
</menu>

View File

@@ -29,4 +29,8 @@
<string name="search_hint">Search word:</string>
<string name="search_description">Search for words in the lexicon</string>
<string name="topics">Topics</string>
<string name="topics_open">Open topics</string>
<string name="topics_close">Close topics</string>
</resources>

View File

@@ -5,19 +5,30 @@ import java.util.*;
import android.app.Activity;
import android.app.ListActivity;
import android.content.Context;
import android.content.res.Configuration;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.*;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.MenuItem;
import android.view.LayoutInflater;
import android.webkit.WebView;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.AdapterView;
import android.util.Log;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.app.ActionBarDrawerToggle;
import org.grammaticalframework.pgf.*;
import org.grammaticalframework.ui.android.LanguageSelector.OnLanguageSelectedListener;
@@ -28,6 +39,9 @@ public class AlternativesActivity extends ListActivity {
private LanguageSelector mShowLanguageView;
private View mProgressBarView = null;
private AlternativesAdapter mAdapter = null;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
/** Called when the activity is first created. */
@Override
@@ -64,23 +78,44 @@ public class AlternativesActivity extends ListActivity {
}.execute();
}
});
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_drawer,
R.string.topics_open,
R.string.topics_close);
mDrawerLayout.setDrawerListener(mDrawerToggle);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
TextView descrView = (TextView) findViewById(R.id.lexical_desc);
String authority = getIntent().getData().getAuthority();
String source = getIntent().getData().getQueryParameter("source");
List analyses = new ArrayList();
for (String an : getIntent().getData().getQueryParameters("alternative")) {
analyses.add(Expr.readExpr(an));
}
descrView.setText(source);
if (getIntent().getData() != null) {
String authority = getIntent().getData().getAuthority();
String source = getIntent().getData().getQueryParameter("source");
mAdapter = new AlternativesAdapter(this, authority, analyses);
List analyses = new ArrayList();
for (String an : getIntent().getData().getQueryParameters("alternative")) {
analyses.add(Expr.readExpr(an));
}
descrView.setText(source);
mAdapter = new AlternativesAdapter(this, authority, analyses);
} else {
mDrawerLayout.openDrawer(Gravity.LEFT);
mAdapter = new AlternativesAdapter(this, Translator.WORDS);
}
expandedView = null;
setListAdapter(mAdapter);
expandedView = null;
mDrawerList = (ListView) findViewById(R.id.topics_list);
mDrawerList.setAdapter(mAdapter.getTopicsAdapter());
mProgressBarView = findViewById(R.id.progressBarView);
}
}
@Override
protected void onResume() {
@@ -98,7 +133,7 @@ public class AlternativesActivity extends ListActivity {
}
private View expandedView;
private void collapse() {
if (expandedView == null)
return;
@@ -182,22 +217,183 @@ public class AlternativesActivity extends ListActivity {
expandedView = view;
}
private class AlternativesAdapter extends ArrayAdapter<Expr> {
private String mAuthority;
private class Topic {
public String name;
public Expr expr;
public boolean isChecked;
public boolean isAvailable;
public Topic(String name, Expr expr) {
this.name = name;
this.expr = expr;
this.isChecked = false;
this.isAvailable = true;
}
}
public AlternativesAdapter(Context context, String authority, List<Expr> data) {
super(context, android.R.layout.simple_list_item_1, data);
mAuthority = authority;
}
private class AlternativesAdapter extends BaseAdapter implements ListAdapter {
/**
* Contains the list of objects that represent the alternatives
*/
private List<Expr> mAlternatives;
private Context mContext;
// A copy of the original mAlternatives array, initialized from and then used instead as soon as
// a topic filtering is applied. mAlternatives will then only contain the filtered values.
private ArrayList<Expr> mOriginalAlternatives;
private LayoutInflater mInflater;
private String mAuthority;
/**
* A list of lists of topics. Each element in this list contains
* the list of topics for the correponding item in
* mAlternatives/mOriginalAlternatives
*/
private List<List<Topic>> mTopics;
private Map<String,Topic> mTopicMap;
private Topic[] mAllTopics;
private Topic[] mOriginalAllTopics;
private Topic mOtherTopic;
private Topic mSourceTopic;
private TopicsAdapter mTopicsAdapter;
public AlternativesAdapter(Context context, String authority, List<Expr> alternatives) {
mContext = context;
mAuthority = authority;
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mAlternatives = alternatives;
boolean addOther = false;
mTopics = new ArrayList<List<Topic>>();
mTopicMap = new TreeMap<String,Topic>();
for (Expr e : mAlternatives) {
List<Topic> topics = new ArrayList<Topic>();
for (Expr topicExpr : mTranslator.getTopicsOf(e)) {
String name = mTranslator.linearizeSource(topicExpr);
String key = name.toLowerCase();
Topic topic = mTopicMap.get(key);
if (topic == null) {
topic = new Topic(name, topicExpr);
mTopicMap.put(key,topic);
}
topics.add(topic);
}
mTopics.add(topics);
if (topics.size() == 0)
addOther = true;
}
int i = 0;
mAllTopics = new Topic[mTopicMap.size() + (addOther ? 1 : 0)];
for (Map.Entry<String,Topic> entry : mTopicMap.entrySet()) {
mAllTopics[i++] = entry.getValue();
}
if (addOther) {
Expr topicExpr = Expr.readExpr("other_1_A");
String name = mTranslator.linearizeSource(topicExpr);
mOtherTopic = new Topic(name, topicExpr);
mAllTopics[i++] = mOtherTopic;
}
mOriginalAllTopics = mAllTopics;
mTopicsAdapter = new TopicsAdapter();
}
public AlternativesAdapter(Context context, String authority) {
mContext = context;
mAuthority = authority;
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mAlternatives = null;
mTopics = null;
int i = 0;
mTopicMap = new TreeMap<String,Topic>();
for (Expr topicExpr : mTranslator.getTopicsOf(null)) {
String name = mTranslator.linearizeSource(topicExpr);
String key = name.toLowerCase();
Topic topic = mTopicMap.get(key);
if (topic == null) {
topic = new Topic(name, topicExpr);
mTopicMap.put(key,topic);
}
}
mAllTopics = new Topic[mTopicMap.size()];
for (Map.Entry<String,Topic> entry : mTopicMap.entrySet()) {
mAllTopics[i++] = entry.getValue();
}
mOriginalAllTopics = mAllTopics;
mTopicsAdapter = new TopicsAdapter();
}
/**
* Returns the context associated with this array adapter. The context is used
* to create views from the resource passed to the constructor.
*
* @return The Context associated with this adapter.
*/
public Context getContext() {
return mContext;
}
public String getAuthority() {
return mAuthority;
}
/**
* {@inheritDoc}
*/
public int getCount() {
if (mAlternatives == null)
return 0;
else
return mAlternatives.size();
}
/**
* {@inheritDoc}
*/
public Expr getItem(int position) {
return mAlternatives.get(position);
}
/**
* Returns the position of the specified item in the array.
*
* @param item The item to retrieve the position of.
*
* @return The position of the specified item.
*/
public int getPosition(Expr item) {
if (mAlternatives == null)
return -1;
else
return mAlternatives.indexOf(item);
}
/**
* {@inheritDoc}
*/
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
final Expr expr = getItem(position);
if (mAuthority.equals(Translator.WORDS)) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater)
getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.lexical_item, null);
convertView = mInflater.inflate(R.layout.lexical_item, null);
}
TextView descView = (TextView)
@@ -221,9 +417,7 @@ public class AlternativesActivity extends ListActivity {
});
} else if (mAuthority.equals(Translator.SENTENCES)) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater)
getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.alternative_item, null);
convertView = mInflater.inflate(R.layout.alternative_item, null);
View treeView = (View) convertView.findViewById(R.id.desc_details);
((RelativeLayout) convertView).removeView(treeView);
@@ -283,5 +477,192 @@ public class AlternativesActivity extends ListActivity {
return convertView;
}
public boolean areAllItemsEnabled() {
return true;
}
public boolean isEnabled(int position) {
return true;
}
public TopicsAdapter getTopicsAdapter() {
return mTopicsAdapter;
}
void filterOnTopics(List<Topic> selected_topics) {
if (mSourceTopic != null && !selected_topics.contains(mSourceTopic))
mAlternatives = null;
if (mAlternatives == null) {
if (selected_topics.size() == 0)
return;
mSourceTopic = selected_topics.get(0);
mAlternatives = mTranslator.getTopicWords(mSourceTopic.expr);
mTopics = new ArrayList<List<Topic>>();
for (Expr e : mAlternatives) {
List<Topic> topics = new ArrayList<Topic>();
for (Expr topicExpr : mTranslator.getTopicsOf(e)) {
String name = mTranslator.linearizeSource(topicExpr);
String key = name.toLowerCase();
topics.add(mTopicMap.get(key));
}
mTopics.add(topics);
}
}
if (mOriginalAlternatives == null) {
mOriginalAlternatives = new ArrayList<Expr>(mAlternatives);
}
mAlternatives = new ArrayList<Expr>();
List<List<Expr>> topics = new ArrayList<List<Expr>>();
for (Topic topic : mOriginalAllTopics) {
topic.isAvailable = false;
}
int count = 0;
for (int i = 0; i < mOriginalAlternatives.size(); i++) {
boolean match = true;
for (Topic topic : selected_topics) {
if (topic == mOtherTopic) {
if (mTopics.get(i).size() > 0) {
match = false;
break;
}
} else if (!mTopics.get(i).contains(topic)) {
match = false;
break;
}
}
if (match) {
mAlternatives.add(mOriginalAlternatives.get(i));
if (mTopics.get(i).size() == 0) {
if (!mOtherTopic.isAvailable)
count++;
mOtherTopic.isAvailable = true;
} else {
for (Topic topic : mTopics.get(i)) {
if (!topic.isAvailable)
count++;
topic.isAvailable = true;
}
}
}
}
int i = 0;
mAllTopics = new Topic[count];
for (Topic topic : mOriginalAllTopics) {
if (topic.isAvailable)
mAllTopics[i++] = topic;
}
notifyDataSetChanged();
}
}
private class TopicsAdapter extends BaseAdapter implements ListAdapter {
public TopicsAdapter() {
}
public Context getContext() {
return mAdapter.getContext();
}
public int getCount() {
return mAdapter.mAllTopics.length;
}
public Topic getItem(int position) {
return mAdapter.mAllTopics[position];
}
public int getPosition(Topic topic) {
for (int i = 0; i < mAdapter.mAllTopics.length; i++) {
if (mAdapter.mAllTopics[i] == topic)
return i;
}
return -1;
}
public long getItemId(int position) {
return position;
}
// Shame on you Google this class should not have been here
// but unfortuantely CheckBox.setChecked doesn't work and here
// we need a workarround. Since the class is there now it is also
// used to implement OnClickListener.
private class TopicCheckBox extends CheckBox implements OnClickListener {
private Topic mTopic;
public TopicCheckBox(Context context, Topic topic) {
super(context);
mTopic = topic;
setOnClickListener(this);
}
@Override
public boolean isChecked() {
if (mTopic == null)
return false;
else
return mTopic.isChecked;
}
@Override
public void onClick(View view) {
mTopic.isChecked = !mTopic.isChecked;
filterOnTopics();
notifyDataSetChanged();
}
}
private void filterOnTopics() {
List<Topic> selected_topics = new ArrayList<Topic>();
for (int i = 0; i < getCount(); i++) {
Topic topic = getItem(i);
if (topic.isChecked)
selected_topics.add(topic);
}
mAdapter.filterOnTopics(selected_topics);
}
public View getView(int position, View convertView, ViewGroup parent) {
Topic entry = getItem(position);
CheckBox checkBox = new TopicCheckBox(getContext(), entry);
checkBox.setText(entry.name);
checkBox.setTextSize(25);
checkBox.setTextColor(android.graphics.Color.parseColor("#808080"));
return checkBox;
}
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Pass the event to ActionBarDrawerToggle, if it returns
// true, then it has handled the app icon touch event
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

View File

@@ -191,8 +191,8 @@ public class MainActivity extends Activity {
editor.commit();
return true;
case R.id.semantic_graph: {
Intent myIntent = new Intent(MainActivity.this, SemanticGraphActivity.class);
case R.id.topics: {
Intent myIntent = new Intent(MainActivity.this, AlternativesActivity.class);
MainActivity.this.startActivity(myIntent);
return true;
}

View File

@@ -338,11 +338,26 @@ public class Translator {
if (s == null)
s = "% "; // make sure that we return something
if (getTargetLanguage().getLangCode().equals("cmn-Hans-CN") ||
getTargetLanguage().getLangCode().equals("ja-JP") ||
getTargetLanguage().getLangCode().equals("th-TH"))
return implode(s) ;
else return s ;
if (getTargetLanguage().getLangCode().equals("cmn-Hans-CN") ||
getTargetLanguage().getLangCode().equals("ja-JP") ||
getTargetLanguage().getLangCode().equals("th-TH"))
return implode(s);
else
return s;
}
public String linearizeSource(Expr expr) {
Concr targetLang = getSourceConcr();
String s = targetLang.linearize(expr);
if (s == null)
s = "% "; // make sure that we return something
if (getTargetLanguage().getLangCode().equals("cmn-Hans-CN") ||
getTargetLanguage().getLangCode().equals("ja-JP") ||
getTargetLanguage().getLangCode().equals("th-TH"))
return implode(s);
else
return s;
}
public Object[] bracketedLinearize(Expr expr) {
@@ -443,15 +458,34 @@ public class Translator {
}
}
private Expr getTopicWords(Expr lemma) {
StringBuilder sbuilder = new StringBuilder();
public List<Expr> getTopicWords(Expr lemma) {
TripleResult res = null;
List<Expr> words = new ArrayList<Expr>();
try {
TripleResult res = mSGManager.queryTriple(null, topic_pred, lemma);
res = mSGManager.queryTriple(null, topic_pred, lemma);
while (res.hasNext()) {
words.add(res.getSubject());
}
} catch (IOException e) {
// nothing
} catch (SGError e) {
// nothing
} finally {
if (res != null)
res.close();
}
return words;
}
private Expr getTopicWordsHtml(Expr lemma) {
StringBuilder sbuilder = new StringBuilder();
TripleResult res = null;
try {
res = mSGManager.queryTriple(null, topic_pred, lemma);
Map<String,Uri.Builder> map = new TreeMap<String,Uri.Builder>();
while (res.hasNext()) {
updateWordsMap(res.getSubject(), map);
}
res.close();
StringBuilder builder = new StringBuilder();
buildWordsHtml(map, builder);
@@ -460,6 +494,9 @@ public class Translator {
// nothing
} catch (SGError e) {
// nothing
} finally {
if (res != null)
res.close();
}
return null;
}
@@ -483,9 +520,9 @@ public class Translator {
Expr e = new Expr("MkDocument",
def,
new Expr("Inflection"+cat,lemma),
getTopicWords(lemma));
getTopicWordsHtml(lemma));
String html =
"<html><head><meta charset=\"UTF-8\"/><style>a {color: gray;}</style></head><body>" +
"<html><head><meta charset=\"UTF-8\"/><style>a {color: #808080;}</style></head><body>" +
targetLang.linearize(e) +
"</body>";
return html;
@@ -495,7 +532,26 @@ public class Translator {
return null;
}
}
public List<Expr> getTopicsOf(Expr lemma) {
TripleResult res = null;
List<Expr> topics = new ArrayList<Expr>();
try {
res = mSGManager.queryTriple(lemma, topic_pred, null);
while (res.hasNext()) {
topics.add(res.getObject());
}
} catch (IOException e) {
// nothing
} catch (SGError e) {
// nothing
} finally {
if (res != null)
res.close();
}
return topics;
}
private static String escapeHtml(CharSequence text) {
StringBuilder out = new StringBuilder();