/**
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 2 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/>.
**/
/**
This file is part of Save For Offline, an Android app which saves / downloads complete webpages for offine reading.
**/
/**
If you modify, redistribute, or write something based on this or parts of it, you MUST,
I repeat, you MUST comply with the GPLv2+ license. This means that if you use or modify
my code, you MUST release the source code of your modified version, if / when this is
required under the terms of the license.
If you cannot / do not want to do this, DO NOT USE MY CODE. Thanks.
(I've added this message to to the source because it's been used in severeral proprietary
closed source apps, which I don't want, and which is also a violation of the liense.)
**/
/**
Written by Jonas Czech (JonasCz, stackoverflow.com/users/4428462/JonasCz and github.com/JonasCz). (4428462jonascz/eafc4d1afq)
**/
package jonas.tool.saveForOffline;
import android.content.*;
import android.database.*;
import android.database.sqlite.*;
import android.graphics.*;
import android.graphics.drawable.*;
import android.os.*;
import android.preference.*;
import android.util.*;
import android.view.*;
import android.widget.*;
import java.io.*;
import java.lang.ref.*;
import java.text.*;
import java.util.*;
import com.squareup.picasso.Picasso;
public class DisplayAdapter extends BaseAdapter {
public enum SortOrder {
NEWEST_FIRST, OLDEST_FIRST, ALPHABETICAL;
public static int toInt (SortOrder o) {
switch (o) {
case OLDEST_FIRST:
return 1;
case ALPHABETICAL:
return 2;
default:
return 0;
}
}
public static SortOrder fromInt (int i) {
switch (i) {
case 1:
return OLDEST_FIRST;
case 2:
return ALPHABETICAL;
default:
return NEWEST_FIRST;
}
}
}
public enum Layout {
DEFAULT, GRID, DETAILS_THUMBNAILS, SMALL_TEXT_ONLY, SMALL_ICON;
private static Layout currentLayout = DEFAULT;
public static void setCurrentLayout (Layout l) {
currentLayout = l;
}
public static Layout getCurrentLayout () {
return currentLayout;
}
public static Layout fromInt (int i) {
switch (i) {
case 2:
return GRID;
case 4:
return DETAILS_THUMBNAILS;
case 5:
return SMALL_TEXT_ONLY;
case 6:
return SMALL_ICON;
default:
return DEFAULT;
}
}
public static boolean hasDate (Layout l) {
return l == Layout.DETAILS_THUMBNAILS || l == Layout.SMALL_TEXT_ONLY || l == Layout.DEFAULT;
}
}
private Context mContext;
private SQLiteDatabase dataBase;
private FuzzyDateFormatter fuzzyFormatter;
private String searchQuery = "";
private String sqlStatement;
private boolean darkMode;
public List<Integer> selectedViewsPositions = new ArrayList<Integer>();
private Bitmap placeHolder;
public Cursor dbCursor;
public void refreshData(String searchQuery, SortOrder order, boolean dataSetChanged) {
switch (order) {
case OLDEST_FIRST:
sqlStatement = "SELECT * FROM " + Database.TABLE_NAME + " WHERE " + Database.TITLE + " LIKE'%" + searchQuery + "%' ORDER BY " + Database.ID + " ASC";
break;
case ALPHABETICAL:
sqlStatement = "SELECT * FROM " + Database.TABLE_NAME + " WHERE " + Database.TITLE + " LIKE'%" + searchQuery + "%' ORDER BY " + Database.TITLE + " ASC";
break;
default: //newest first
sqlStatement = "SELECT * FROM " + Database.TABLE_NAME + " WHERE " + Database.TITLE + " LIKE'%" + searchQuery + "%' ORDER BY " + Database.ID + " DESC";
break;
}
dbCursor = dataBase.rawQuery(sqlStatement, null);
dbCursor.moveToFirst();
if (dataSetChanged) notifyDataSetChanged();
}
public DisplayAdapter(Context c) {
this.mContext = c;
dataBase = new Database(c).getReadableDatabase();
fuzzyFormatter = new FuzzyDateFormatter(Calendar.getInstance());
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(mContext);
Layout.setCurrentLayout(Layout.fromInt(Integer.parseInt(sharedPref.getString("layout" , "1"))));
darkMode = sharedPref.getBoolean("dark_mode", false);
refreshData(null, SortOrder.NEWEST_FIRST, false);
placeHolder = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.icon_website_large);
}
public String getSearchQuery() {
return searchQuery;
}
@Override
public boolean isEmpty() {
return dbCursor.getCount() == 0;
}
public int getCount() {
return dbCursor.getCount();
}
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
if (dbCursor.getCount() != 0) {
return Long.valueOf(dbCursor.getString(dbCursor.getColumnIndex(Database.ID)));
} else return 0;
}
public String getPropertiesByPosition(int position, String type) {
dbCursor.moveToPosition(position);
return dbCursor.getString(dbCursor.getColumnIndex(type));
}
private View inflateView (View convertView, Holder mHolder) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
switch (Layout.getCurrentLayout()) {
case GRID:
convertView = layoutInflater.inflate(R.layout.listcell_grid, null); break;
case DETAILS_THUMBNAILS:
convertView = layoutInflater.inflate(R.layout.listcell_list_details, null); break;
case SMALL_TEXT_ONLY:
convertView = layoutInflater.inflate(R.layout.listcell_list_details_small, null); break;
case SMALL_ICON:
convertView = layoutInflater.inflate(R.layout.listcell_list_details_small_icon_only, null); break;
default:
convertView = layoutInflater.inflate(R.layout.listcell_default, null);
}
if (darkMode) {
convertView.setBackgroundColor(Color.BLACK);
if (Layout.hasDate(Layout.getCurrentLayout())) {
mHolder.txt_date = (TextView) convertView.findViewById(R.id.txt_date);
mHolder.txt_date.setTextColor(Color.WHITE);
}
mHolder.txt_id = (TextView) convertView.findViewById(R.id.txt_id);
mHolder.txt_filelocation = (TextView) convertView.findViewById(R.id.txt_fileLocation);
mHolder.txt_orig_url = (TextView) convertView.findViewById(R.id.txt_orig_url);
mHolder.txt_orig_url.setTextColor(Color.WHITE);
mHolder.txt_title = (TextView) convertView.findViewById(R.id.txt_title);
mHolder.txt_title.setTextColor(Color.WHITE);
} else {
if (Layout.hasDate(Layout.getCurrentLayout())) {
mHolder.txt_date = (TextView) convertView.findViewById(R.id.txt_date);
}
mHolder.txt_id = (TextView) convertView.findViewById(R.id.txt_id);
mHolder.txt_filelocation = (TextView) convertView.findViewById(R.id.txt_fileLocation);
mHolder.txt_orig_url = (TextView) convertView.findViewById(R.id.txt_orig_url);
mHolder.txt_title = (TextView) convertView.findViewById(R.id.txt_title);
}
if (Layout.getCurrentLayout() != Layout.SMALL_TEXT_ONLY) {
mHolder.listimage = (ImageView) convertView.findViewById(R.id.listimage);
}
convertView.setTag(mHolder);
return convertView;
}
private void setListImage (ImageView imageView) {
if (Layout.getCurrentLayout() == Layout.SMALL_TEXT_ONLY) return;
switch ((String) imageView.getTag()) {
case "show:icon":
File icon = new File(new File(dbCursor.getString(dbCursor.getColumnIndex(Database.THUMBNAIL))).getParent(), "saveForOffline_icon.png");
Picasso.with(mContext).load(icon).error(R.drawable.icon_website_large).into(imageView);
break;
case "show:thumbnail":
File image = new File(dbCursor.getString(dbCursor.getColumnIndex(Database.THUMBNAIL)));
Picasso.with(mContext).load(image).placeholder(R.drawable.placeholder).into(imageView);
break;
default:
Log.e("displayAdapter", "Bug: image / icon not set due to imageView.getTag() returning bad value:" + imageView.getTag());
}
}
public View getView(int position, View convertView, ViewGroup parent) {
dbCursor.moveToPosition(position);
Holder mHolder = null;
if (convertView == null) {
mHolder = new Holder();
convertView = inflateView(convertView, mHolder);
} else {
mHolder = (Holder) convertView.getTag();
}
if (selectedViewsPositions.contains(position)) {
convertView.setBackgroundColor(Color.parseColor("#FFC107"));
} else {
if (darkMode) {
convertView.setBackgroundColor(Color.BLACK);
} else {
convertView.setBackgroundColor(Color.parseColor("#E2E2E2"));
}
}
if (Layout.hasDate(Layout.getCurrentLayout()) && "show:date".equals(mHolder.txt_date.getTag())) {
try {
mHolder.txt_date.setText("Saved " + fuzzyFormatter.getFuzzy(dbCursor.getString(dbCursor.getColumnIndex(Database.TIMESTAMP))));
} catch (ParseException e) {
Log.e("displayAdapter", "attempted to parse date '" + dbCursor.getString(dbCursor.getColumnIndex(Database.TIMESTAMP)) + "' for display, with format yyyy-MM-dd HH:mm:ss, which resulted in a ParseException");
mHolder.txt_date.setText("Date unavailable");
}
}
mHolder.txt_id.setText(dbCursor.getString(dbCursor.getColumnIndex(Database.ID)));
mHolder.txt_filelocation.setText(dbCursor.getString(dbCursor.getColumnIndex(Database.FILE_LOCATION)));
mHolder.txt_orig_url.setText(dbCursor.getString(dbCursor.getColumnIndex(Database.ORIGINAL_URL)));
mHolder.txt_title.setText(dbCursor.getString(dbCursor.getColumnIndex(Database.TITLE)));
setListImage(mHolder.listimage);
return convertView;
}
static class Holder {
TextView txt_id;
TextView txt_filelocation;
TextView txt_orig_url;
TextView txt_title;
TextView txt_date;
ImageView listimage;
Bitmap mBitmap;
}
}