Added search options to exclude trash and junk folder

pull/199/head
M66B 4 years ago
parent b52c3171c4
commit bce33a421a

@ -224,12 +224,30 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
" index=" + state.index +
" matches=" + (state.matches == null ? null : state.matches.size()));
long[] exclude = new long[0];
if (account == null) {
List<Long> folders = new ArrayList<>();
if (!criteria.in_trash) {
List<EntityFolder> trash = db.folder().getFoldersByType(EntityFolder.TRASH);
if (trash != null)
for (EntityFolder folder : trash)
folders.add(folder.id);
}
if (!criteria.in_junk) {
List<EntityFolder> junk = db.folder().getFoldersByType(EntityFolder.JUNK);
if (junk != null)
for (EntityFolder folder : junk)
folders.add(folder.id);
}
exclude = Helper.toLongArray(folders);
}
int found = 0;
if (criteria.fts && criteria.query != null) {
if (state.ids == null) {
SQLiteDatabase sdb = FtsDbHelper.getInstance(context);
state.ids = FtsDbHelper.match(sdb, account, folder, criteria);
state.ids = FtsDbHelper.match(sdb, account, folder, exclude, criteria);
EntityLog.log(context, "Boundary FTS " +
" account=" + account +
" folder=" + folder +
@ -258,7 +276,7 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
if (state.matches == null ||
(state.matches.size() > 0 && state.index >= state.matches.size())) {
state.matches = db.message().matchMessages(
account, folder,
account, folder, exclude,
criteria.query == null ? null : "%" + criteria.query + "%",
criteria.in_senders,
criteria.in_recipients,
@ -692,6 +710,8 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
boolean with_notes;
String[] with_types;
Integer with_size = null;
boolean in_trash = true;
boolean in_junk = true;
Long after = null;
Long before = null;

@ -226,6 +226,9 @@ public interface DaoFolder {
" WHERE account = :account AND type = :type")
EntityFolder getFolderByType(long account, String type);
@Query("SELECT * FROM folder WHERE type = :type")
List<EntityFolder> getFoldersByType(String type);
@Query("SELECT folder.* FROM folder" +
" JOIN account ON account.id = folder.account" +
" WHERE account.synchronize" +

@ -346,11 +346,12 @@ public interface DaoMessage {
" AND (:size IS NULL OR total > :size)" +
" AND (:after IS NULL OR received > :after)" +
" AND (:before IS NULL OR received < :before)" +
" AND NOT message.folder IN (:exclude)" +
" GROUP BY message.id" +
" ORDER BY matched DESC, received DESC" +
" LIMIT :limit OFFSET :offset")
List<TupleMatch> matchMessages(
Long account, Long folder, String find,
Long account, Long folder, long[] exclude, String find,
boolean senders, boolean recipients, boolean subject, boolean keywords, boolean message, boolean notes, boolean headers,
boolean unseen, boolean flagged, boolean hidden, boolean encrypted, boolean with_attachments, boolean with_notes,
int type_count, String[] types,

@ -78,6 +78,8 @@ public class FragmentDialogSearch extends FragmentDialogBase {
boolean last_search_keywords = prefs.getBoolean("last_search_keywords", false);
boolean last_search_message = prefs.getBoolean("last_search_message", true);
boolean last_search_notes = prefs.getBoolean("last_search_notes", true);
boolean last_search_trash = prefs.getBoolean("last_search_trash", true);
boolean last_search_junk = prefs.getBoolean("last_search_junk", true);
View dview = LayoutInflater.from(context).inflate(R.layout.dialog_search, null);
@ -110,6 +112,8 @@ public class FragmentDialogSearch extends FragmentDialogBase {
final CheckBox cbEncrypted = dview.findViewById(R.id.cbEncrypted);
final CheckBox cbAttachments = dview.findViewById(R.id.cbAttachments);
final Spinner spMessageSize = dview.findViewById(R.id.spMessageSize);
final CheckBox cbSearchTrash = dview.findViewById(R.id.cbSearchTrash);
final CheckBox cbSearchJunk = dview.findViewById(R.id.cbSearchJunk);
final Button btnBefore = dview.findViewById(R.id.btnBefore);
final Button btnAfter = dview.findViewById(R.id.btnAfter);
final TextView tvBefore = dview.findViewById(R.id.tvBefore);
@ -214,6 +218,8 @@ public class FragmentDialogSearch extends FragmentDialogBase {
grpMore.setVisibility(View.GONE);
cbHeaders.setVisibility(View.GONE);
cbHtml.setVisibility(View.GONE);
cbSearchTrash.setVisibility(View.GONE);
cbSearchJunk.setVisibility(View.GONE);
} else {
ibMore.setImageLevel(0);
grpMore.setVisibility(View.VISIBLE);
@ -221,6 +227,10 @@ public class FragmentDialogSearch extends FragmentDialogBase {
cbHeaders.setVisibility(View.VISIBLE);
cbHtml.setVisibility(View.VISIBLE);
}
if (account < 0) {
cbSearchTrash.setVisibility(View.VISIBLE);
cbSearchJunk.setVisibility(View.VISIBLE);
}
}
}
};
@ -308,6 +318,20 @@ public class FragmentDialogSearch extends FragmentDialogBase {
}
});
cbSearchTrash.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
prefs.edit().putBoolean("last_search_trash", isChecked).apply();
}
});
cbSearchJunk.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
prefs.edit().putBoolean("last_search_junk", isChecked).apply();
}
});
btnAfter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -333,10 +357,14 @@ public class FragmentDialogSearch extends FragmentDialogBase {
cbNotes.setChecked(last_search_notes);
tvAfter.setText(null);
tvBefore.setText(null);
cbSearchTrash.setChecked(last_search_trash);
cbSearchJunk.setChecked(last_search_junk);
grpMore.setVisibility(View.GONE);
cbHeaders.setVisibility(View.GONE);
cbHtml.setVisibility(View.GONE);
cbSearchTrash.setVisibility(View.GONE);
cbSearchJunk.setVisibility(View.GONE);
final AlertDialog dialog = new AlertDialog.Builder(context)
.setView(dview)
@ -390,6 +418,9 @@ public class FragmentDialogSearch extends FragmentDialogBase {
}
}
criteria.in_trash = cbSearchTrash.isChecked();
criteria.in_junk = cbSearchJunk.isChecked();
Object after = tvAfter.getTag();
Object before = tvBefore.getTag();

@ -137,7 +137,7 @@ public class FtsDbHelper extends SQLiteOpenHelper {
static List<Long> match(
SQLiteDatabase db,
Long account, Long folder,
Long account, Long folder, long[] exclude,
BoundaryCallbackMessages.SearchCriteria criteria) {
List<String> word = new ArrayList<>();
@ -200,6 +200,15 @@ public class FtsDbHelper extends SQLiteOpenHelper {
select += "account = " + account + " AND ";
if (folder != null)
select += "folder = " + folder + " AND ";
if (exclude.length > 0) {
select += "NOT folder IN (";
for (int i = 0; i < exclude.length; i++) {
if (i > 0)
select += ", ";
select += exclude[i];
}
select += ") AND ";
}
if (criteria.after != null)
select += "time > " + criteria.after + " AND ";
if (criteria.before != null)

@ -470,6 +470,28 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/spMessageSize" />
<CheckBox
android:id="@+id/cbSearchTrash"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_search_in_trash"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvSizeHint" />
<CheckBox
android:id="@+id/cbSearchJunk"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_search_in_junk"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbSearchTrash" />
<Button
android:id="@+id/btnAfter"
style="?android:attr/buttonStyleSmall"
@ -480,7 +502,7 @@
android:text="@string/title_search_with_after"
app:layout_constraintEnd_toStartOf="@id/btnBefore"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvSizeHint" />
app:layout_constraintTop_toBottomOf="@id/cbSearchJunk" />
<Button
android:id="@+id/btnBefore"
@ -492,7 +514,7 @@
android:text="@string/title_search_with_before"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btnAfter"
app:layout_constraintTop_toBottomOf="@id/tvSizeHint" />
app:layout_constraintTop_toBottomOf="@id/cbSearchJunk" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvAfter"

@ -1212,6 +1212,8 @@
<string name="title_search_with_encrypted">Encrypted (on device only)</string>
<string name="title_search_with_attachments">With attachments (on device only)</string>
<string name="title_search_with_size">Message size larger than</string>
<string name="title_search_in_trash">In trash</string>
<string name="title_search_in_junk">In spam</string>
<string name="title_search_with_before">Before</string>
<string name="title_search_with_after">After</string>
<string name="title_search_flag_unseen">unread</string>

Loading…
Cancel
Save