package com.applang.tagesberichte;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import android.app.Activity;
import android.app.ExpandableListActivity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseExpandableListAdapter;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageButton;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.TextView;
import static com.applang.Util.*;
import static com.applang.Util2.*;
import com.applang.Util;
import com.applang.Util.Job;
import com.applang.berichtsheft.R;
import com.applang.provider.NotePadProvider;
import com.applang.provider.NotePad.NoteColumns;
public class Glossary extends ExpandableListActivity
{
private static final String TAG = Glossary.class.getSimpleName();
public static void setThreaded(Context context, boolean value) {
SharedPreferences prefs = context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = prefs.edit();
prefsEditor.putBoolean("threaded", value);
prefsEditor.commit();
}
public static boolean getThreaded(Context context, boolean defaultValue) {
SharedPreferences prefs = context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
return prefs.getBoolean("threaded", defaultValue);
}
private static final int MENU_ITEM_VIEW = Menu.FIRST;
private static final int MENU_ITEM_REFRESH = Menu.FIRST + 1;
private static final int MENU_ITEM_SEARCH = Menu.FIRST + 2;
public ExpandableListView listView;
public GlossaryListAdapter adapter;
public ContentResolver contentResolver;
private static final String[] PROJECTION = new String[] {
NoteColumns._ID, // 0
NoteColumns.TITLE, // 1
NoteColumns.CREATED_DATE,
};
private Uri mUri;
private int tableIndex;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.glossary);
final Intent intent = getIntent();
mUri = intent.getData();
tableIndex = NotePadProvider.tableIndex(2, mUri);
if (mUri == null)
mUri = NotePadProvider.contentUri(tableIndex);
adapter = new GlossaryListAdapter(this, new GlossaryTree());
Helper.listViewSearch(true, this, adapter.getFilter());
listView = getExpandableListView();
listView.setOnChildClickListener(new OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
// Toast.makeText(getBaseContext(), "Child clicked", Toast.LENGTH_LONG).show();
return false;
}
});
listView.setOnGroupClickListener(new OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
// Toast.makeText(getBaseContext(), "Group clicked", Toast.LENGTH_LONG).show();
return false;
}
});
listView.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
if (ExpandableListView.getPackedPositionType(id) == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
int groupPosition = ExpandableListView.getPackedPositionGroup(id);
int childPosition = ExpandableListView.getPackedPositionChild(id);
clickInfo = adapter.getChild(groupPosition, childPosition);
openContextMenu(listView);
return true;
}
if (ExpandableListView.getPackedPositionType(id) == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
int groupPosition = ExpandableListView.getPackedPositionGroup(id);
clickInfo = adapter.getGroup(groupPosition);
openContextMenu(listView);
return true;
}
return false;
}
});
listView.setAdapter(adapter);
registerForContextMenu(listView);
contentResolver = getContentResolver();
setContentObserver();
needsRefresh = true;
}
private void setContentObserver() {
super.onStart();
ContentObserver contentObserver = new ContentObserver(notifyHandler) {
public void onChange(boolean selfChange) {
if (isRunning)
repopulate();
else
needsRefresh = true;
}
};
Uri notificationUri = NotePadProvider.contentUri(NotePadProvider.tableName(tableIndex));
if (contentObserver != null)
contentResolver.registerContentObserver(notificationUri, true, contentObserver);
}
ContentObserver contentObserver = null;
private void resetContentObserver() {
if (contentObserver != null)
contentResolver.unregisterContentObserver(contentObserver);
}
@Override
protected void onDestroy() {
resetContentObserver();
super.onStop();
}
public void populate(boolean clear) {
if (clear)
adapter.clear();
Cursor cursor = null;
try {
cursor = contentResolver.query(NotePadProvider.contentUri(tableIndex),
PROJECTION,
"", null,
NoteColumns.TITLE_SORT_ORDER);
if (cursor.moveToFirst())
do {
adapter.addItem(new GlossaryLeaf(Glossary.this, cursor.getString(1), cursor.getLong(2)));
} while (cursor.moveToNext());
notifyHandler.sendEmptyMessage(1);
Util.delay(50);
Log.i(TAG, "Glossary populated");
}
finally {
if (cursor != null)
cursor.close();
}
}
private void repopulate() {
boolean threaded = getThreaded(this, true);
if (threaded) {
WorkerThread worker = new WorkerThread(this, new Job<Activity>() {
public void perform(Activity activity, Object[] params) throws Exception {
populate(true);
}
}, null);
worker.start();
}
else
populate(true);
}
private Handler notifyHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
adapter.notifyDataSetInvalidated();
break;
case 2:
adapter.notifyDataSetChanged();
break;
}
super.handleMessage(msg);
}
};
private Object clickInfo = null;
private boolean needsRefresh = false;
private boolean isRunning = false;
@Override
protected void onPause() {
super.onPause();
isRunning = false;
}
@Override
protected void onResume() {
super.onResume();
isRunning = true;
if (needsRefresh) {
repopulate();
needsRefresh = false;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, MENU_ITEM_SEARCH, 0, R.string.menu_search)
.setShortcut('5', 's')
.setIcon(android.R.drawable.ic_menu_search);
menu.add(0, MENU_ITEM_REFRESH, 0, R.string.menu_refresh)
.setShortcut('6', 'r');
menu.add(0, MENU_ITEM_VIEW, 0, R.string.menu_view)
.setShortcut('7', 'v')
.setIcon(android.R.drawable.ic_menu_view);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_ITEM_VIEW:
startActivityForResult(
new Intent(GlossaryView.GLOSSARY_VIEW_ACTION, mUri), 0);
return true;
case MENU_ITEM_REFRESH:
repopulate();
return true;
case MENU_ITEM_SEARCH:
Helper.listViewSearch(false, this, null);
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, view, menuInfo);
if (clickInfo != null) {
menu.setHeaderTitle(clickInfo.toString());
getMenuInflater().inflate(R.menu.contextmenu_glossary, menu);
// if (clickInfo instanceof String)
// menu.removeItem(R.id.menu_item_evaluate);
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
/* case R.id.menu_item_evaluate:
if (clickInfo instanceof GlossaryLeaf) {
GlossaryLeaf glossaryLeaf = (GlossaryLeaf) clickInfo;
Uri uri = ContentUris.withAppendedId(NotePadProvider.contentUri(0), glossaryLeaf.getRefId());
startActivity(new Intent()
.setClass(this, NoteEvaluator.class)
.setData(uri));
}
return true;
*/
case R.id.menu_item_edit:
if (clickInfo instanceof GlossaryLeaf) {
GlossaryLeaf glossaryLeaf = (GlossaryLeaf) clickInfo;
long id = NotePadProvider.getIdOfNote(contentResolver, tableIndex,
NoteColumns.TITLE + "=? and " + NoteColumns.CREATED_DATE + "=?",
strings(glossaryLeaf.getGroup(), "" + glossaryLeaf.getRefId()));
Uri uri = ContentUris.withAppendedId(mUri, id);
startActivity(new Intent()
.setClass(this, TitleEditor.class)
.setData(uri)
.putExtra("state", NoteEditor.STATE_EDIT));
}
else if (clickInfo instanceof String) {
startActivity(new Intent()
.setClass(this, TitleEditor.class)
.setData(mUri)
.putExtra("title", clickInfo.toString())
.putExtra("state", NoteEditor.STATE_EDIT));
}
return true;
case R.id.menu_item_remove:
String message = getResources().getString(R.string.areUsure, clickInfo.toString());
if (clickInfo instanceof GlossaryLeaf) {
areUsure(this, message, new Job<Void>() {
@Override
public void perform(Void t, Object[] params) throws Exception {
GlossaryLeaf glossaryLeaf = (GlossaryLeaf) clickInfo;
adapter.removeItem(glossaryLeaf);
contentResolver.delete(mUri,
NoteColumns.TITLE + "=? and " + NoteColumns.CREATED_DATE + "=?",
new String[]{glossaryLeaf.getGroup(), "" + glossaryLeaf.getRefId()});
}
});
}
else if (clickInfo instanceof String) {
areUsure(this, message, new Job<Void>() {
@Override
public void perform(Void t, Object[] params) throws Exception {
String group = clickInfo.toString();
adapter.removeItem(new GlossaryLeaf(null, group, -1));
contentResolver.delete(mUri,
NoteColumns.TITLE + "=?",
new String[]{group});
}
});
}
else
return false;
return true;
}
return false;
}
public class GlossaryLeaf
{
@Override
public String toString() {
return NotesList.description(0, epoch, title);
}
public GlossaryLeaf(Activity activity, String group, long refId) {
this.refId = refId;
if (activity != null) {
Cursor cursor = null;
try {
cursor = contentResolver.query(NotePadProvider.contentUri(0),
PROJECTION,
NoteColumns._ID + "= ?",
new String[] { "" + refId },
NoteColumns.DEFAULT_SORT_ORDER);
if (cursor.moveToFirst()) {
this.title = cursor.getString(1);
this.epoch = cursor.getLong(2);
}
} finally {
if (cursor != null)
cursor.close();
}
}
this.group = group;
}
private String group;
public String getGroup() {
return group;
}
private String title = "";
public String getTitle() {
return title;
}
private long epoch = 0;
public long getEpoch() {
return epoch;
}
private long refId;
public long getRefId() {
return refId;
}
}
class GlossaryBranch extends ArrayList<GlossaryLeaf>
{
}
class GlossaryTree extends LinkedHashMap<String, GlossaryBranch>
{
}
public class GlossaryListAdapter extends BaseExpandableListAdapter implements Filterable
{
private Activity activity;
private GlossaryTree tree, origTree = null;
public GlossaryListAdapter(Activity activity, GlossaryTree tree) {
this.activity = activity;
this.tree = tree;
}
Filter glossaryFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
if (origTree == null)
origTree = tree;
if (notNullOrEmpty(constraint)) {
tree = new GlossaryTree();
String crit = constraint.toString().toLowerCase(Locale.getDefault());
for (Map.Entry<String, GlossaryBranch> entry : origTree.entrySet()) {
String s = entry.getKey();
if (s.toLowerCase(Locale.getDefault()).startsWith(crit))
tree.put(s, entry.getValue());
}
}
else if (origTree != null)
tree = origTree;
FilterResults results = new FilterResults();
results.values = tree;
results.count = tree.size();
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count < 1)
notifyDataSetInvalidated();
else
notifyDataSetChanged();
}
};
@Override
public Filter getFilter() {
return glossaryFilter;
}
@Override
public boolean areAllItemsEnabled() {
return true;
}
public void addItem(GlossaryLeaf glossaryLeaf) {
String group = glossaryLeaf.getGroup();
GlossaryBranch branch;
if (tree.keySet().contains(group))
branch = tree.get(group);
else {
branch = new GlossaryBranch();
tree.put(group, branch);
}
branch.add(glossaryLeaf);
}
public void removeItem(GlossaryLeaf glossaryLeaf) {
String group = glossaryLeaf.getGroup();
if (tree.keySet().contains(group)) {
GlossaryBranch branch = tree.get(group);
if (branch.contains(glossaryLeaf))
branch.remove(glossaryLeaf);
if (branch.size() < 1)
tree.remove(group);
}
}
public void clear() {
tree.clear();
}
GlossaryBranch getBranch(int groupPosition) {
return tree.get(getGroup(groupPosition));
}
@Override
public Object getChild(int groupPosition, int childPosition) {
GlossaryBranch branch = getBranch(groupPosition);
return branch == null ? null : branch.get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public int getChildrenCount(int groupPosition) {
GlossaryBranch branch = getBranch(groupPosition);
return branch == null ? 0 : branch.size();
}
@Override
public Object getGroup(int groupPosition) {
String[] groups = tree.keySet().toArray(new String[0]);
if (groupPosition > -1 && groupPosition < groups.length)
return groups[groupPosition];
else
return null;
}
@Override
public int getGroupCount() {
return tree.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int arg0, int arg1) {
return true;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.noteslist_item2, null);
}
TextView tv = (TextView) convertView.findViewById(R.id.title);
String group = (String) getGroup(groupPosition);
tv.setText(group);
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.noteslist_item, null);
}
GlossaryLeaf leaf = (GlossaryLeaf) getChild(groupPosition, childPosition);
if (leaf != null) {
TextView tv = (TextView) convertView.findViewById(R.id.date);
tv.setText(NotesList.formatDate(leaf.getEpoch()));
tv = (TextView) convertView.findViewById(R.id.title);
tv.setText(leaf.getTitle());
}
// android.graphics.drawable.Drawable icon = context.getResources().getDrawable( R.drawable.note );
// tv.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
return convertView;
}
}
}