/**
* Odoo, Open Source Management Solution
* Copyright (C) 2012-today Odoo SA (<http:www.odoo.com>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http:www.gnu.org/licenses/>
*
* Created on 8/1/15 12:44 PM
*/
package com.odoo.core.support.list;
import android.content.Context;
import android.database.Cursor;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.CursorAdapter;
import android.widget.SectionIndexer;
import com.odoo.core.orm.ODataRow;
import com.odoo.core.utils.logger.OLog;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import odoo.controls.OForm;
public class OCursorListAdapter extends CursorAdapter implements
AdapterView.OnItemClickListener, SectionIndexer {
public static final String TAG = OCursorListAdapter.class.getSimpleName();
private Integer mLayout = null;
private LayoutInflater mInflater = null;
private OnViewCreateListener mOnViewCreateListener = null;
private HashMap<Integer, OnRowViewClickListener> mViewClickListeners = new HashMap<>();
private HashMap<String, View> mViewCache = new HashMap<String, View>();
private Boolean mCacheViews = false;
private OnViewBindListener mOnViewBindListener = null;
private BeforeBindUpdateData mBeforeBindUpdateData = null;
private Context mContext = null;
private IOnItemClickListener mIOnItemClickListener = null;
private AbsListView mListView = null;
private Boolean hasIndexers = false;
private String mIndexerColumn = null;
private HashMap<String, Integer> azIndexers = new HashMap<>();
private String[] sections = new String[0];
public OCursorListAdapter(Context context, Cursor c, int layout) {
super(context, c, false);
mLayout = layout;
mInflater = LayoutInflater.from(context);
mContext = context;
}
public OCursorListAdapter allowCacheView(Boolean cache) {
mCacheViews = cache;
return this;
}
public View getCachedView(Cursor cr) {
int pos = cr.getPosition();
if (mViewCache.size() > pos) {
return mViewCache.get("view_" + pos);
}
return null;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
final ODataRow row = new ODataRow();
for (String col : cursor.getColumnNames()) {
row.put(col, getValue(cursor, col));
}
if (mBeforeBindUpdateData != null) {
row.addAll(mBeforeBindUpdateData.updateDataRow(cursor));
}
if (view instanceof OForm) {
OForm form = (OForm) view;
form.initForm(row);
}
if (mOnViewBindListener != null) {
mOnViewBindListener.onViewBind(view, cursor, row);
}
}
@Override
public View getView(final int position, View view, ViewGroup viewGroup) {
Cursor cursor = (Cursor) getItem(position);
view = getCachedView(cursor);
if (mCacheViews && view != null) {
return view;
}
view = newView(mContext, cursor, (ViewGroup) view);
final View mView = view;
for (final int id : mViewClickListeners.keySet()) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (mView.findViewById(id) != null) {
mView.findViewById(id).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
OnRowViewClickListener listener = mViewClickListeners
.get(id);
Cursor c = getCursor();
c.moveToPosition(position);
listener.onRowViewClick(position, c, v,
mView);
}
});
} else {
OLog.log("View @id/"
+ mContext.getResources().getResourceEntryName(
id) + " not found");
}
}
}, 100);
}
return super.getView(position, view, viewGroup);
}
private Object getValue(Cursor c, String column) {
Object value = false;
int index = c.getColumnIndex(column);
switch (c.getType(index)) {
case Cursor.FIELD_TYPE_NULL:
value = false;
break;
case Cursor.FIELD_TYPE_BLOB:
case Cursor.FIELD_TYPE_STRING:
value = c.getString(index);
break;
case Cursor.FIELD_TYPE_FLOAT:
value = c.getFloat(index);
break;
case Cursor.FIELD_TYPE_INTEGER:
value = c.getInt(index);
break;
}
return value;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
View view;
if (mCacheViews && getCachedView(cursor) != null) {
view = getCachedView(cursor);
if (!view.isDirty()) {
return view;
}
}
if (mOnViewCreateListener != null) {
view = mOnViewCreateListener.onViewCreated(context, viewGroup,
cursor, cursor.getPosition());
if (view == null) {
view = mInflater.inflate(mLayout, viewGroup, false);
}
} else
view = mInflater.inflate(mLayout, viewGroup, false);
if (mCacheViews) {
mViewCache.put("view_" + cursor.getPosition(), view);
}
return view;
}
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
if (hasIndexers && mIndexerColumn != null) {
Cursor cr = getCursor();
if (cr.getCount() > 0) {
int pos = 0;
if (cr.moveToFirst()) {
List<String> keys = new ArrayList<>();
do {
int index = cr.getColumnIndex(mIndexerColumn);
if (index > -1) {
String colValue = cr.getString(index);
azIndexers.put(colValue.substring(0, 1), pos);
keys.add(colValue.substring(0, 1));
}
pos++;
} while (cr.moveToNext());
Collections.sort(keys);
sections = keys.toArray(new String[keys.size()]);
}
}
}
}
public View inflate(int resource, ViewGroup viewGroup) {
return mInflater.inflate(resource, viewGroup, false);
}
public int getResource() {
return mLayout;
}
public void setOnRowViewClickListener(int view_id,
OnRowViewClickListener listener) {
mViewClickListeners.put(view_id, listener);
}
public void setOnViewCreateListener(OnViewCreateListener viewCreateListener) {
mOnViewCreateListener = viewCreateListener;
}
public void setOnViewBindListener(OnViewBindListener bindListener) {
mOnViewBindListener = bindListener;
}
public void setBeforeBindUpdateData(BeforeBindUpdateData updater) {
mBeforeBindUpdateData = updater;
}
public interface OnRowViewClickListener {
public void onRowViewClick(int position, Cursor cursor, View view,
View parent);
}
public interface OnViewBindListener {
public void onViewBind(View view, Cursor cursor, ODataRow row);
}
public interface BeforeBindUpdateData {
public ODataRow updateDataRow(Cursor cr);
}
public interface OnViewCreateListener {
public View onViewCreated(Context context, ViewGroup view, Cursor cr,
int position);
}
public void handleItemClickListener(AbsListView absListView, IOnItemClickListener listener) {
mIOnItemClickListener = listener;
mListView = absListView;
if (mListView != null && mIOnItemClickListener != null) {
mListView.setOnItemClickListener(this);
}
}
private Boolean mDoubleClick = false;
private Integer mDoubleClickItemIndex = -1;
@Override
public void onItemClick(AdapterView<?> parent, final View view, final int position, long id) {
if (mDoubleClick && mDoubleClickItemIndex == position) {
mDoubleClick = false;
mIOnItemClickListener.onItemDoubleClick(view, position);
} else {
mDoubleClick = true;
mDoubleClickItemIndex = position;
}
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (mDoubleClick) {
mDoubleClick = false;
mDoubleClickItemIndex = -1;
mIOnItemClickListener.onItemClick(view, position);
}
}
}, 500);
}
public void setHasSectionIndexers(boolean hasSectionIndexers, String onColumn) {
hasIndexers = hasSectionIndexers;
mIndexerColumn = onColumn;
}
// Section Indexers
@Override
public Object[] getSections() {
return sections;
}
@Override
public int getPositionForSection(int sectionIndex) {
return azIndexers.get(sections[sectionIndex]);
}
@Override
public int getSectionForPosition(int position) {
return azIndexers.get(sections[position]);
}
}