/** * Copyright (c) 2012 Vinayak Solutions Private Limited * See the file license.txt for copying permission. */ package com.vinsol.expensetracker.expenselisting; import java.io.File; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Adapter; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.ImageView.ScaleType; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import com.vinsol.expensetracker.Constants; import com.vinsol.expensetracker.R; import com.vinsol.expensetracker.expenselisting.dialog.AudioPlayDialog; import com.vinsol.expensetracker.expenselisting.dialog.DescriptionDialog; import com.vinsol.expensetracker.expenselisting.dialog.GroupedIconDialogClickListener; import com.vinsol.expensetracker.expenselisting.dialog.UnknownEntryDialog; import com.vinsol.expensetracker.helpers.CheckEntryComplete; import com.vinsol.expensetracker.helpers.DateHelper; import com.vinsol.expensetracker.helpers.DisplayDate; import com.vinsol.expensetracker.helpers.FileHelper; import com.vinsol.expensetracker.helpers.StringProcessing; import com.vinsol.expensetracker.models.Entry; import com.vinsol.expensetracker.models.ListDatetimeAmount; import com.vinsol.expensetracker.utils.ImagePreview; import com.vinsol.expensetracker.utils.Log; class SeparatedListAdapter extends BaseAdapter { public final Map<String, ArrayAdapter<Entry>> sections = new LinkedHashMap<String, ArrayAdapter<Entry>>(); public final ArrayAdapter<String> headers; public final ArrayAdapter<String> footers; public final static int TYPE_SECTION_HEADER = 0; public final static int TYPE_SECTION_FOOTER = 0; private Context mContext; private List<ListDatetimeAmount> mDataDateList; private LayoutInflater mInflater; private UnknownEntryDialog unknownEntryDialog; private View viewHeader = null; private View viewFooter = null; private String highlightID; private FileHelper fileHelper; public SeparatedListAdapter(Context context,String highlightID) { mContext = context; this.highlightID = highlightID; if(this.highlightID == null) { highlightID = ""; } headers = new ArrayAdapter<String>(context,R.layout.mainlist_header_view); footers = new ArrayAdapter<String>(context,R.layout.main_list_footerview); mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); fileHelper = new FileHelper(); } public void addSection(String section, ArrayAdapter<Entry> adapter,List<ListDatetimeAmount> mDataDateList) { this.mDataDateList = mDataDateList; Log.d("*********** Amount *************"); Log.d(" amon "+mDataDateList.get(0).amount); this.headers.add(section); this.footers.add(section); this.sections.put(section, adapter); } @Override public Object getItem(int position) { for (Object section : sections.keySet()) { Adapter adapter = sections.get(section); int size = adapter.getCount() + 2; // check if position inside this section if (position == 0) { return section; } if (position < size - 1) { return adapter.getItem(position - 1); } if (position < size) { return section; } // otherwise jump into next section position -= size; } return null; } @Override public int getCount() { // total together all sections, plus one for each section header int total = 0; for (Adapter adapter : this.sections.values()) total += adapter.getCount() + 2; return total; } @Override public int getViewTypeCount() { // assume that headers count as one, then total all sections int total = 2; for (Adapter adapter : this.sections.values()) total += adapter.getViewTypeCount(); return total; } @Override public int getItemViewType(int position) { int type = 1; for (Object section : this.sections.keySet()) { Adapter adapter = sections.get(section); int size = adapter.getCount() + 2; // check if position inside this section if (position == 0) return TYPE_SECTION_HEADER; if (position < size - 1) { return type + adapter.getItemViewType(position - 1); } if (position < size) return TYPE_SECTION_FOOTER; // otherwise jump into next section position -= size; type += adapter.getViewTypeCount(); } return -1; } @Override public boolean isEnabled(int position) { return (getItemViewType(position) != TYPE_SECTION_HEADER); } @Override public View getView(int position, View convertView, ViewGroup parent) { int sectionnum = 0; ViewHolderHeader holderHeader; ViewHolderBody holderBody; ViewHolderFooter holderFooter; for (Object section : this.sections.keySet()) { ArrayAdapter<Entry> adapter = sections.get(section); int size = adapter.getCount() + 2; // check if position inside this section if (position == 0) { holderHeader = new ViewHolderHeader(); viewHeader = mInflater.inflate(R.layout.mainlist_header_view,null); holderHeader.listDateView = (TextView) viewHeader.findViewById(R.id.expenses_listing_list_date_view); holderHeader.listAmountView = (TextView) viewHeader.findViewById(R.id.expenses_listing_list_amount_view); holderHeader.listDateView.setText(mDataDateList.get(sectionnum).dateTime); holderHeader.listAmountView.setText(new StringProcessing().getStringDoubleDecimal(mDataDateList.get(sectionnum).amount)); return viewHeader; } if (position == size-1) { holderFooter = new ViewHolderFooter(); viewFooter = mInflater.inflate(R.layout.main_list_footerview, null); holderFooter.addExpensesButton = (Button) viewFooter.findViewById(R.id.expenses_listing_add_expenses_button); holderFooter.addExpenses = (LinearLayout) viewFooter.findViewById(R.id.expense_listing_list_add_expenses); if (!isCurrentWeek(mDataDateList.get(sectionnum).dateTime)) { holderFooter.addExpenses.setBackgroundResource(0); holderFooter.addExpenses.setVisibility(View.GONE); holderFooter.addExpensesButton.setVisibility(View.GONE); } else { holderFooter.addExpensesButton.setText("Add expenses to "+ mDataDateList.get(sectionnum).dateTime); holderFooter.addExpensesButton.setFocusable(false); DateHelper mDateHelper = new DateHelper(mDataDateList.get(sectionnum).dateTime); holderFooter.addExpensesButton.setOnClickListener(new GroupedIconDialogClickListener(unknownEntryDialog, (Activity)mContext, null, mDateHelper.getTimeMillis())); } return viewFooter; } if (position > 0 && position < size - 1) { if (convertView == null) { holderBody = new ViewHolderBody(); convertView = mInflater.inflate(R.layout.expense_listing_inflated_row, null); holderBody.rowLocationTime = (TextView) convertView.findViewById(R.id.row_location_time); holderBody.rowTag = (TextView) convertView.findViewById(R.id.row_tag); holderBody.rowAmount = (TextView) convertView.findViewById(R.id.row_amount); holderBody.rowImageview = (ImageView) convertView.findViewById(R.id.row_imageview); holderBody.dividerImageView = (ImageView) convertView.findViewById(R.id.row_imageview_divider); holderBody.rowFavoriteIcon = (ImageView) convertView.findViewById(R.id.row_favorite_icon); holderBody.rowListview = (RelativeLayout) convertView.findViewById(R.id.row_listview); convertView.setTag(holderBody); } else { holderBody = (ViewHolderBody) convertView.getTag(); } if(holderBody.bitmap != null) {holderBody.bitmap.recycle();} holderBody.rowImageview.setScaleType(ScaleType.CENTER_INSIDE); Entry mlist = (Entry) adapter.getItem(position - 1); CheckEntryComplete mCheckEntryComplete = new CheckEntryComplete(); if (mlist.type.equals(mContext.getString(R.string.camera))) { setBackGround(holderBody,mCheckEntryComplete,mlist); if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { try { File mFile = fileHelper.getCameraFileThumbnailEntry(mlist.id); if (mFile.canRead()) { holderBody.bitmap = BitmapFactory.decodeFile(mFile.getPath()); holderBody.rowImageview.setImageBitmap(holderBody.bitmap); holderBody.rowImageview.setScaleType(ScaleType.FIT_CENTER); } else { holderBody.rowImageview.setScaleType(ScaleType.CENTER_INSIDE); holderBody.rowImageview.setImageResource(R.drawable.no_image_small); } } catch (Exception e) { holderBody.rowImageview.setImageResource(R.drawable.no_image_small); } } else { holderBody.rowImageview.setImageResource(R.drawable.no_image_small); } } else if (mlist.type.equals(mContext.getString(R.string.text))) { setBackGround(holderBody, mCheckEntryComplete, mlist); if (!mlist.description.equals(mContext.getString(R.string.unfinished_textentry)) && !mlist.description.equals(mContext.getString(R.string.finished_textentry))) { holderBody.rowImageview.setImageResource(R.drawable.listing_text_entry_icon); } else { holderBody.rowImageview.setImageResource(R.drawable.text_list_icon_no_tag); } } else if (mlist.type.equals(mContext.getString(R.string.unknown))) { holderBody.rowImageview.setImageResource(R.drawable.listing_reminder_icon); holderBody.rowListview.setBackgroundResource(R.drawable.listing_row_unknown_states); } else if (mlist.type.equals(mContext.getString(R.string.voice))) { setBackGround(holderBody, mCheckEntryComplete, mlist); File mFile = fileHelper.getAudioFileEntry(mlist.id); if (mFile.canRead()) { holderBody.rowImageview.setImageResource(R.drawable.listing_voice_entry_icon); } else { holderBody.rowImageview.setImageResource(R.drawable.no_voice_file_small); } } if (mlist.favorite != null) { if(!mlist.favorite.equals("")) { try{ if(isCurrentWeek(mDataDateList.get(sectionnum).dateTime)) { holderBody.rowFavoriteIcon.setVisibility(View.VISIBLE); } else { holderBody.rowFavoriteIcon.setVisibility(View.INVISIBLE); } }catch(Exception e) { } }else { holderBody.rowFavoriteIcon.setVisibility(View.INVISIBLE); } }else { holderBody.rowFavoriteIcon.setVisibility(View.INVISIBLE); } holderBody.rowImageview.setFocusable(false); holderBody.rowImageview.setOnClickListener(new MyClickListener(mlist)); if (mlist.timeInMillis != null && !mlist.timeInMillis.equals("")) { holderBody.rowLocationTime.setText(new DisplayDate().getLocationDate(mlist.timeInMillis, mlist.location)); } else if ((mlist.timeInMillis == null || mlist.timeInMillis.equals(""))&& mlist.location != null&& !mlist.location.equals("")) { holderBody.rowLocationTime.setText("Unknown time at "+ mlist.location); } else { holderBody.rowLocationTime.setText("Unknown time at Unknown Location"); } holderBody.rowTag.setText(mlist.description); holderBody.rowAmount.setText(new StringProcessing().getStringDoubleDecimal(mlist.amount)); if (mlist.type.equals(mContext.getString(R.string.sublist_thisyear)) || mlist.type.equals(mContext.getString(R.string.sublist_all))|| mlist.type.equals(mContext.getString(R.string.sublist_thismonth))) { holderBody.rowImageview.setVisibility(View.GONE); holderBody.rowLocationTime.setVisibility(View.GONE); holderBody.dividerImageView.setVisibility(View.GONE); } return convertView; } position -= size; sectionnum++; } return null; } @Override public long getItemId(int position) { return position; } public int getListPosition(int position) { int listPosition = 0; for (Object section : sections.keySet()) { Adapter adapter = sections.get(section); int size = adapter.getCount() + 2; if(position <= size) { return listPosition; } listPosition+=adapter.getCount(); position-=size; } return -1; } public boolean remove(int toRemove) { String sectionNumber = getSectionNumber(toRemove); Entry prevEntry = (Entry) getItem(toRemove); if(sections.containsKey(sectionNumber)) { sections.get(sectionNumber).remove((Entry)getItem(toRemove)); if(sections.get(sectionNumber).getCount() == 0) { removeSection(sectionNumber); } else { updateAmount(sectionNumber, prevEntry, null); } notifyDataSetChanged(); return true; } return false; } public void update(Entry updatedEntry,int toUpdate, String sectionNumber, Entry prevEntry) { sections.get(sectionNumber).insert(updatedEntry, toUpdate); sections.get(sectionNumber).remove(prevEntry); updateAmount(sectionNumber, prevEntry, updatedEntry); notifyDataSetChanged(); } public String getSectionNumber(int position) { int sectionNumber = 0; for (Object section : sections.keySet()) { Adapter adapter = sections.get(section); int size = adapter.getCount() + 2; if(position <= size) { return sectionNumber+""; } sectionNumber++; position-=size; } return ""; } public List<ListDatetimeAmount> getDataDateList() { return mDataDateList; } /////////////////**********************Private Classes **********************//////////////////////// private class MyClickListener implements OnClickListener { Entry mListenerList; public MyClickListener(Entry mlist) { mListenerList = mlist; } @Override public void onClick(View v) { switch (v.getId()) { case R.id.row_imageview: if (mListenerList != null) if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { if (mListenerList.type.equals(mContext.getString(R.string.voice))) { File mFile = fileHelper.getAudioFileEntry(mListenerList.id); if (mFile.canRead()) { new AudioPlayDialog(mContext, mListenerList.id); } } else if (mListenerList.type.equals(mContext.getString(R.string.camera))) { File mFile = fileHelper.getCameraFileLargeEntry(mListenerList.id); if (mFile.canRead()) { Intent intent = new Intent(mContext, ImagePreview.class); intent.putExtra(Constants.KEY_ID, mListenerList.id); mContext.startActivity(intent); } } } if (mListenerList.type.equals(mContext.getString(R.string.text))) { if (!mListenerList.description.equals(mContext.getString(R.string.unfinished_textentry))) { new DescriptionDialog(mContext, mListenerList.description); } } break; default: break; } } } private void removeSection(String sectionKey) { sections.remove(sectionKey); mDataDateList.remove(Integer.parseInt(sectionKey)); } private static class ViewHolderBody { TextView rowLocationTime; TextView rowTag; TextView rowAmount; ImageView rowImageview; ImageView rowFavoriteIcon; RelativeLayout rowListview; ImageView dividerImageView; Bitmap bitmap; } private class ViewHolderHeader { TextView listDateView; TextView listAmountView; } private class ViewHolderFooter { Button addExpensesButton; LinearLayout addExpenses; } private void setBackGround(ViewHolderBody holderBody,CheckEntryComplete mCheckEntryComplete,Entry mlist) { // if (mlist.id.equals(highlightID)) { // holderBody.rowListview.setBackgroundResource(R.drawable.listing_row_unfinished_states); // //TODO I dont like the background //// holderBody.rowListview.setBackgroundResource(R.drawable.listing_row_highlighted_entry_states); // } else if(!mCheckEntryComplete.isEntryComplete(mlist,mContext)) { holderBody.rowListview.setBackgroundResource(R.drawable.listing_row_unfinished_states); } else { holderBody.rowListview.setBackgroundResource(R.drawable.listing_row_states); } } private boolean isCurrentWeek(String dateViewString) { if(dateViewString != null) { if(!dateViewString.equals("")) { return new DateHelper(dateViewString).isCurrentWeek(); } } return false; } private void updateAmount(String sectionNumber, Entry prevEntry, Entry updatedEntry) { StringProcessing mStringProcessing = new StringProcessing(); Double amountDouble = mStringProcessing.getAmount(mDataDateList.get(Integer.parseInt(sectionNumber)).amount); amountDouble -= mStringProcessing.getAmount(prevEntry.amount); if(updatedEntry != null && !updatedEntry.amount.contains("?")) { updatedEntry.amount = mStringProcessing.getStringDoubleDecimal(updatedEntry.amount); amountDouble += mStringProcessing.getAmount(updatedEntry.amount); } if(amountDouble != 0.0 && mDataDateList.get(Integer.parseInt(sectionNumber)).amount.contains("?")) { mDataDateList.get(Integer.parseInt(sectionNumber)).amount = mStringProcessing.getStringDoubleDecimal(amountDouble+"?"); } else if(amountDouble == 0.0 && mDataDateList.get(Integer.parseInt(sectionNumber)).amount.contains("?")) { mDataDateList.get(Integer.parseInt(sectionNumber)).amount = mStringProcessing.getStringDoubleDecimal("?"); } else { mDataDateList.get(Integer.parseInt(sectionNumber)).amount = mStringProcessing.getStringDoubleDecimal(amountDouble+""); } } }