/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.doplgangr.secrecy.adapters;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.ViewAnimator;
import com.doplgangr.secrecy.Config;
import com.doplgangr.secrecy.CustomApp;
import com.doplgangr.secrecy.events.ThumbLoadDoneEvent;
import com.doplgangr.secrecy.exceptions.SecrecyFileException;
import com.doplgangr.secrecy.filesystem.files.EncryptedFile;
import com.doplgangr.secrecy.R;
import com.doplgangr.secrecy.utils.Util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import de.greenrobot.event.EventBus;
public class FilesListAdapter extends RecyclerView.Adapter<FilesListAdapter.ViewHolder> {
private final Context context;
private boolean isGallery;
private final int layout;
// store (a reference to) the data
private final List<EncryptedFile> data = new ArrayList<EncryptedFile>();
private final Set<Integer> selectedItems = new HashSet<Integer>();
private OnItemClickListener onItemClickListener;
private OnItemLongClickListener onLongClickListener;
public FilesListAdapter(Context context, boolean isGallery) {
this.isGallery = false;
this.context = context;
this.isGallery = isGallery;
layout = isGallery ? R.layout.gallery_item : R.layout.file_item;
if (!EventBus.getDefault().isRegistered(this))
EventBus.getDefault().register(this);
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public void setOnLongClickListener(OnItemLongClickListener onLongClickListener) {
this.onLongClickListener = onLongClickListener;
}
/**
* Add data to data set.
*/
public void add(EncryptedFile encryptedFile) {
if (encryptedFile == null)
return;
if (encryptedFile.getDecryptedFileName() == null)
return;
if (isGallery) {
String mimeType = Util.getFileTypeFromExtension(encryptedFile.getFileExtension());
if (mimeType != null)
if (!mimeType.contains("image"))
return;
}
if (!data.contains(encryptedFile)) {
data.add(encryptedFile);
}
notifyItemInserted(data.size() - 1);
}
public void remove(int position) {
data.remove(position);
notifyItemRemoved(position);
}
public void remove(List<Integer> selected) {
// Remove items in reverse order to keep indices in order
Collections.sort(selected, Collections.reverseOrder());
for (Integer i : selected) {
data.remove((int) i);
notifyItemRemoved(i);
}
}
/**
* Return the size of the data set.
*/
@Override
public int getItemCount() {
return this.data.size();
}
/**
* Return if index is in data set.
*/
public boolean hasIndex(int position) {
return this.data.size() > position && position > -1;
}
/**
* Return an object in the data set.
*/
public EncryptedFile getItem(int position) {
return this.data.get(position);
}
/**
* Return the position provided.
*/
public int getItemId(EncryptedFile encryptedFile) {
return data.indexOf(encryptedFile);
}
public void onEventMainThread(ThumbLoadDoneEvent event) {
try {
String name = (String) event.imageView.getTag();
if (name.equals(event.encryptedFile.getDecryptedFileName()) && (event.bitmap != null) && (event.imageView != null)) {
event.imageView.setImageBitmap(event.bitmap); // bind thumbnail in UI thread
event.imageView.setVisibility(View.VISIBLE);
}
} catch (OutOfMemoryError ignored) {
}
}
boolean isSelected(int position){
return selectedItems.contains(position);
}
public boolean select(int position) {
if (isSelected(position)){
selectedItems.remove(position);
return false;
}
selectedItems.add(position);
return true;
}
public Set<Integer> getSelected() {
return selectedItems;
}
public void clearSelected() {
selectedItems.clear();
notifyDataSetChanged();
}
public void clear() {
data.clear();
selectedItems.clear();
}
public void sort() {
Comparator<EncryptedFile> comparator;
switch (PreferenceManager.getDefaultSharedPreferences(context).getString(
Config.VAULT_SORT, Config.VAULT_SORT_ALPHABETIC)) {
case Config.VAULT_SORT_ALPHABETIC:
comparator = Config.COMPARATOR_ENCRYPTEDFILE_ALPHABETIC;
break;
case Config.VAULT_SORT_FILETYPE:
comparator = Config.COMPARATOR_ENCRYPTEDFILE_FILETYPE;
break;
case Config.VAULT_SORT_LASTMODIFIED:
comparator = Config.COMPARATOR_ENCRYPTEDFILE_LASTMODIFIED;
break;
default:
comparator = null;
}
if (comparator != null) {
Collections.sort(data, comparator);
notifyDataSetChanged();
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(layout, viewGroup, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(final ViewHolder viewHolder, int position) {
final EncryptedFile encryptedFile = this.data.get(position);
if (viewHolder.name != null){
viewHolder.name.setText(encryptedFile.getDecryptedFileName());
}
if (viewHolder.type != null) {
viewHolder.type.setText(encryptedFile.getType());
}
if (viewHolder.size != null) {
viewHolder.size.setText(encryptedFile.getFileSize());
}
if (viewHolder.date != null) {
viewHolder.date.setText(encryptedFile.getTimestamp());
}
if (viewHolder.thumbnail != null) {
viewHolder.thumbnail.setVisibility(View.GONE);
viewHolder.thumbnail.setTag(encryptedFile.getDecryptedFileName());
}
if (viewHolder.frame != null) {
viewHolder.frame.setForeground(isSelected(position) ?
context.getResources().getDrawable(R.drawable.file_selector) :
null);
}
if (viewHolder.progressBar != null){
encryptedFile.setProgressBar(viewHolder.progressBar);
encryptedFile.getProgressBar().setMax((int) encryptedFile.getFile().length());
}
if (viewHolder.animator != null) {
viewHolder.animator.setDisplayedChild(viewHolder.page);
int viewIndex;
if (data.get(position).getIsDecrypting()){
viewIndex = 1;
} else {
viewHolder.animator.setInAnimation(null);
viewIndex = 0;
}
viewHolder.animator.setDisplayedChild(viewIndex);
}
final int avatar_size = (int) CustomApp.context.getResources().getDimension(R.dimen.list_item_avatar_size);
// This class is for binding thumbnail to UI
class BindImageTask extends AsyncTask<EncryptedFile, Void, Bitmap> {
protected Bitmap doInBackground(EncryptedFile... files) {
if (isGallery) {
try {
return files[0].getEncryptedThumbnail().getThumb(100);
} catch (SecrecyFileException e) {
Util.log("No bitmap available!");
}
}
try {
return files[0].getEncryptedThumbnail().getThumb(avatar_size); // async decrypt thumbnail
} catch (SecrecyFileException e) {
Util.log("No bitmap available!");
}
return null;
}
protected void onPostExecute(Bitmap thumbnail) {
String name = (String) viewHolder.thumbnail.getTag();
if (name.equals(encryptedFile.getDecryptedFileName()) && (thumbnail != null) && (viewHolder.thumbnail != null)) {
viewHolder.thumbnail.setImageBitmap(thumbnail); // bind thumbnail in UI thread
viewHolder.thumbnail.setVisibility(View.VISIBLE);
}
}
}
new BindImageTask().execute(encryptedFile);
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public final TextView name;
public final TextView type;
public final TextView size;
public final TextView date;
public final ImageView thumbnail;
public final FrameLayout frame;
public final ViewAnimator animator;
public final ProgressBar progressBar;
public int page;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
type = (TextView) itemView.findViewById(R.id.type);
size = (TextView) itemView.findViewById(R.id.size);
date = (TextView) itemView.findViewById(R.id.date);
thumbnail = (ImageView) itemView.findViewById(R.id.thumbNail);
frame = (FrameLayout) itemView.findViewById(R.id.frame);
frame.setTag(this);
animator = (ViewAnimator) itemView.findViewById(R.id.viewAnimator);
progressBar = (ProgressBar) itemView.findViewById(R.id.progressBar);
frame.setOnClickListener(this);
frame.setOnLongClickListener(this);
}
@Override
public void onClick(View view) {
if (onItemClickListener != null) {
onItemClickListener.onItemClick(view, getPosition());
}
}
@Override
public boolean onLongClick(View view) {
if (onLongClickListener != null){
onLongClickListener.onItemLongClick(view, getPosition());
return true;
}
return false;
}
}
public interface OnItemClickListener {
public void onItemClick(View view , int position);
}
public interface OnItemLongClickListener {
public boolean onItemLongClick(View view , int position);
}
}