/* * Copyright (C) 2015 Federico Iosue (federico.iosue@gmail.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package it.feio.android.omninotes.models.adapters; import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.net.Uri; import android.os.AsyncTask; import android.support.annotation.NonNull; import android.text.Spanned; import android.util.Log; import android.util.SparseBooleanArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import com.bumptech.glide.Glide; import com.nhaarman.listviewanimations.util.Insertable; import it.feio.android.omninotes.R; import it.feio.android.omninotes.async.TextWorkerTask; import it.feio.android.omninotes.models.Attachment; import it.feio.android.omninotes.models.Note; import it.feio.android.omninotes.models.holders.NoteViewHolder; import it.feio.android.omninotes.utils.*; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.concurrent.RejectedExecutionException; public class NoteAdapter extends ArrayAdapter<Note> implements Insertable { private final Activity mActivity; private final int navigation; private List<Note> notes = new ArrayList<>(); private SparseBooleanArray selectedItems = new SparseBooleanArray(); private boolean expandedView; private int layout; private LayoutInflater inflater; private long closestNoteReminder = Long.parseLong(Constants.TIMESTAMP_UNIX_EPOCH_FAR); private int closestNotePosition; public NoteAdapter(Activity activity, int layout, List<Note> notes) { super(activity, R.layout.note_layout_expanded, notes); this.mActivity = activity; this.notes = notes; this.layout = layout; expandedView = layout == R.layout.note_layout_expanded; inflater = (LayoutInflater) mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); navigation = Navigation.getNavigation(); manageCloserNote(notes, navigation); } @Override public View getView(int position, View convertView, ViewGroup parent) { Note note = notes.get(position); NoteViewHolder holder; if (convertView == null) { convertView = inflater.inflate(layout, parent, false); holder = buildHolder(convertView, parent); convertView.setTag(holder); } else { holder = (NoteViewHolder) convertView.getTag(); } initText(note, holder); initIcons(note, holder); initDates(note, holder); initThumbnail(note, holder); manageSelectionColor(position, note, holder); return convertView; } /** * Highlighted if is part of multiselection of notes. Remember to search for child with card ui */ private void manageSelectionColor(int position, Note note, NoteViewHolder holder) { if (selectedItems.get(position)) { holder.cardLayout.setBackgroundColor(mActivity.getResources().getColor( R.color.list_bg_selected)); } else { restoreDrawable(note, holder.cardLayout, holder); } } private void initThumbnail(Note note, NoteViewHolder holder) { // Attachment thumbnail if (expandedView) { // If note is locked or without attachments nothing is shown if ((note.isLocked() && !mActivity.getSharedPreferences(Constants.PREFS_NAME, Context.MODE_MULTI_PROCESS).getBoolean("settings_password_access", false)) || note.getAttachmentsList().size() == 0) { holder.attachmentThumbnail.setVisibility(View.GONE); } // Otherwise... else { holder.attachmentThumbnail.setVisibility(View.VISIBLE); Attachment mAttachment = note.getAttachmentsList().get(0); Uri thumbnailUri = BitmapHelper.getThumbnailUri(mActivity, mAttachment); Glide.with(mActivity) .load(thumbnailUri) .centerCrop() .crossFade() .into(holder.attachmentThumbnail); } } } public List<Note> getNotes() { return notes; } private void initDates(Note note, NoteViewHolder holder) { String dateText = TextHelper.getDateText(mActivity, note, navigation); holder.date.setText(dateText); } private void initIcons(Note note, NoteViewHolder holder) { // Evaluates the archived state... holder.archiveIcon.setVisibility(note.isArchived() ? View.VISIBLE : View.GONE); // ...the location holder.locationIcon.setVisibility(note.getLongitude() != null && note.getLongitude() != 0 ? View.VISIBLE : View.GONE); // ...the presence of an alarm holder.alarmIcon.setVisibility(note.getAlarm() != null ? View.VISIBLE : View.GONE); // ...the locked with password state holder.lockedIcon.setVisibility(note.isLocked() ? View.VISIBLE : View.GONE); // ...the attachment icon for contracted view if (!expandedView) { holder.attachmentIcon.setVisibility(note.getAttachmentsList().size() > 0 ? View.VISIBLE : View.GONE); } } private void initText(Note note, NoteViewHolder holder) { try { if (note.isChecklist()) { TextWorkerTask task = new TextWorkerTask(mActivity, holder.title, holder.content, expandedView); task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, note); } else { Spanned[] titleAndContent = TextHelper.parseTitleAndContent(mActivity, note); holder.title.setText(titleAndContent[0]); holder.content.setText(titleAndContent[1]); holder.title.setText(titleAndContent[0]); if (titleAndContent[1].length() > 0) { holder.content.setText(titleAndContent[1]); holder.content.setVisibility(View.VISIBLE); } else { holder.content.setVisibility(View.INVISIBLE); } } } catch (RejectedExecutionException e) { Log.w(Constants.TAG, "Oversized tasks pool to load texts!", e); } } /** * Saves the position of the closest note to align list scrolling with it on start */ private void manageCloserNote(List<Note> notes, int navigation) { if (navigation == Navigation.REMINDERS) { for (int i = 0; i < notes.size(); i++) { long now = Calendar.getInstance().getTimeInMillis(); long reminder = Long.parseLong(notes.get(i).getAlarm()); if (now < reminder && reminder < closestNoteReminder) { closestNotePosition = i; closestNoteReminder = reminder; } } } } /** * Returns the note with the nearest reminder in the future */ public int getClosestNotePosition() { return closestNotePosition; } public SparseBooleanArray getSelectedItems() { return selectedItems; } public void addSelectedItem(Integer selectedItem) { this.selectedItems.put(selectedItem, true); } public void removeSelectedItem(Integer selectedItem) { this.selectedItems.delete(selectedItem); } public void clearSelectedItems() { this.selectedItems.clear(); } public void restoreDrawable(Note note, View v) { restoreDrawable(note, v, null); } public void restoreDrawable(Note note, View v, NoteViewHolder holder) { final int paddingBottom = v.getPaddingBottom(), paddingLeft = v.getPaddingLeft(); final int paddingRight = v.getPaddingRight(), paddingTop = v.getPaddingTop(); v.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); colorNote(note, v, holder); } @SuppressWarnings("unused") private void colorNote(Note note, View v) { colorNote(note, v, null); } /** * Color of category marker if note is categorized a function is active in preferences */ private void colorNote(Note note, View v, NoteViewHolder holder) { String colorsPref = mActivity.getSharedPreferences(Constants.PREFS_NAME, Context.MODE_MULTI_PROCESS) .getString("settings_colors_app", Constants.PREF_COLORS_APP_DEFAULT); // Checking preference if (!colorsPref.equals("disabled")) { // Resetting transparent color to the view v.setBackgroundColor(Color.parseColor("#00000000")); // If category is set the color will be applied on the appropriate target if (note.getCategory() != null && note.getCategory().getColor() != null) { if (colorsPref.equals("complete") || colorsPref.equals("list")) { v.setBackgroundColor(Integer.parseInt(note.getCategory().getColor())); } else { if (holder != null) { holder.categoryMarker.setBackgroundColor(Integer.parseInt(note.getCategory().getColor())); } else { v.findViewById(R.id.category_marker).setBackgroundColor(Integer.parseInt(note.getCategory().getColor())); } } } else { v.findViewById(R.id.category_marker).setBackgroundColor(0); } } } /** * Replaces notes */ public void replace(Note note, int index) { if (notes.indexOf(note) != -1) { notes.remove(index); } else { index = notes.size(); } notes.add(index, note); } @Override public void add(int i, @NonNull Object o) { insert((Note) o, i); } public void remove(List<Note> notes) { for (Note note : notes) { remove(note); } } private NoteViewHolder buildHolder(View convertView, ViewGroup parent) { // Overrides font sizes with the one selected from user Fonts.overrideTextSize(mActivity, mActivity.getSharedPreferences(Constants.PREFS_NAME, Context.MODE_MULTI_PROCESS), convertView); return new NoteViewHolder(convertView); } }