Added searching in attachment filenames

This commit is contained in:
M66B 2023-10-19 09:35:23 +02:00
parent 5415eb4469
commit 010d99869f
6 changed files with 52 additions and 5 deletions

View File

@ -831,6 +831,15 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
return true;
}
if (criteria.in_filenames) {
DB db = DB.getInstance(context);
List<EntityAttachment> attachments = db.attachment().getAttachments(message.id);
if (attachments != null)
for (EntityAttachment attachment : attachments)
if (!TextUtils.isEmpty(attachment.name) && contains(attachment.name, criteria.query, true, false))
return true; // Partial search to find "filename.extension"
}
if (criteria.in_headers) {
if (message.headers != null && message.headers.contains(criteria.query))
return true;
@ -991,6 +1000,7 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
boolean in_keywords = true;
boolean in_message = true;
boolean in_notes = true;
boolean in_filenames = false;
boolean in_headers = false;
boolean in_html = false;
boolean with_unseen;
@ -1276,6 +1286,7 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
this.in_keywords == other.in_keywords &&
this.in_message == other.in_message &&
this.in_notes == other.in_notes &&
this.in_filenames == other.in_filenames &&
this.in_headers == other.in_headers &&
this.in_html == other.in_html &&
this.with_unseen == other.with_unseen &&
@ -1304,6 +1315,7 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
json.put("in_keywords", in_keywords);
json.put("in_message", in_message);
json.put("in_notes", in_notes);
json.put("in_filenames", in_filenames);
json.put("in_headers", in_headers);
json.put("in_html", in_html);
json.put("with_unseen", with_unseen);
@ -1351,6 +1363,7 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
criteria.in_keywords = json.optBoolean("in_keywords");
criteria.in_message = json.optBoolean("in_message");
criteria.in_notes = json.optBoolean("in_notes");
criteria.in_filenames = json.optBoolean("in_filenames");
criteria.in_headers = json.optBoolean("in_headers");
criteria.in_html = json.optBoolean("in_html");
criteria.with_unseen = json.optBoolean("with_unseen");
@ -1399,6 +1412,7 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
" keywords=" + in_keywords +
" message=" + in_message +
" notes=" + in_notes +
" filenames=" + in_filenames +
" headers=" + in_headers +
" html=" + in_html +
" unseen=" + with_unseen +

View File

@ -87,6 +87,7 @@ 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_filenames = prefs.getBoolean("last_search_filenames", false);
boolean last_search_trash = prefs.getBoolean("last_search_trash", true);
boolean last_search_junk = prefs.getBoolean("last_search_junk", true);
boolean last_search_device = prefs.getBoolean("last_search_device", true);
@ -116,6 +117,7 @@ public class FragmentDialogSearch extends FragmentDialogBase {
CheckBox cbMessage = dview.findViewById(R.id.cbMessage);
TextView tvSearchTextUnsupported = dview.findViewById(R.id.tvSearchTextUnsupported);
CheckBox cbNotes = dview.findViewById(R.id.cbNotes);
CheckBox cbFileNames = dview.findViewById(R.id.cbFileNames);
CheckBox cbHeaders = dview.findViewById(R.id.cbHeaders);
CheckBox cbHtml = dview.findViewById(R.id.cbHtml);
CheckBox cbSearchTrash = dview.findViewById(R.id.cbSearchTrash);
@ -343,6 +345,13 @@ public class FragmentDialogSearch extends FragmentDialogBase {
}
});
cbFileNames.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
prefs.edit().putBoolean("last_search_filenames", isChecked).apply();
}
});
cbSearchTrash.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
@ -406,6 +415,7 @@ public class FragmentDialogSearch extends FragmentDialogBase {
tvSearchTextUnsupported.setText(getString(R.string.title_search_text_unsupported,
"full text search not supported"));
cbNotes.setChecked(last_search_notes);
cbFileNames.setChecked(last_search_filenames);
cbSearchTrash.setChecked(last_search_trash);
cbSearchJunk.setChecked(last_search_junk);
tvAfter.setText(null);
@ -437,6 +447,7 @@ public class FragmentDialogSearch extends FragmentDialogBase {
criteria.in_keywords = cbKeywords.isChecked();
criteria.in_message = cbMessage.isChecked();
criteria.in_notes = cbNotes.isChecked();
criteria.in_filenames = cbFileNames.isChecked();
criteria.in_headers = cbHeaders.isChecked();
criteria.in_html = cbHtml.isChecked();
criteria.with_unseen = cbUnseen.isChecked();

View File

@ -45,7 +45,7 @@ public class Fts4DbHelper extends SQLiteOpenHelper {
@SuppressLint("StaticFieldLeak")
private static Fts4DbHelper instance = null;
private static final int DATABASE_VERSION = 1;
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_NAME = "fts4a.db";
private Fts4DbHelper(Context context) {
@ -76,6 +76,7 @@ public class Fts4DbHelper extends SQLiteOpenHelper {
", `keyword`" +
", `text`" +
", `notes`" +
", `filenames`" +
", notindexed=`account`" +
", notindexed=`folder`" +
", notindexed=`time`)");
@ -98,7 +99,7 @@ public class Fts4DbHelper extends SQLiteOpenHelper {
DB.getInstance(context).message().resetFts();
}
static void insert(SQLiteDatabase db, EntityMessage message, String text) {
static void insert(SQLiteDatabase db, EntityMessage message, List<EntityAttachment> attachments, String text) {
Log.i("FTS insert id=" + message.id);
List<Address> address = new ArrayList<>();
if (message.from != null)
@ -110,6 +111,12 @@ public class Fts4DbHelper extends SQLiteOpenHelper {
if (message.bcc != null)
address.addAll(Arrays.asList(message.bcc));
List<String> filenames = new ArrayList<>();
if (attachments != null)
for (EntityAttachment attachment : attachments)
if (!TextUtils.isEmpty(attachment.name))
filenames.add(attachment.name);
delete(db, message.id);
ContentValues cv = new ContentValues();
@ -122,6 +129,7 @@ public class Fts4DbHelper extends SQLiteOpenHelper {
cv.put("keyword", TextUtils.join(" ", message.keywords));
cv.put("text", processBreakText(text));
cv.put("notes", processBreakText(message.notes));
cv.put("filenames", processBreakText(TextUtils.join(" ", filenames)));
db.insertWithOnConflict("message", null, cv, SQLiteDatabase.CONFLICT_FAIL);
}

View File

@ -81,6 +81,8 @@ public class WorkerFts extends Worker {
continue;
}
List<EntityAttachment> attachments = db.attachment().getAttachments(message.id);
String text = null;
if (message.content) {
File file = message.getFile(context);
@ -89,7 +91,7 @@ public class WorkerFts extends Worker {
try {
sdb.beginTransaction();
Fts4DbHelper.insert(sdb, message, text);
Fts4DbHelper.insert(sdb, message, attachments, text);
sdb.setTransactionSuccessful();
} catch (SQLiteException ex) {
Log.w(ex);

View File

@ -363,6 +363,17 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvSearchTextUnsupported" />
<CheckBox
android:id="@+id/cbFileNames"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_search_in_filenames"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbNotes" />
<CheckBox
android:id="@+id/cbHeaders"
android:layout_width="0dp"
@ -372,7 +383,7 @@
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbNotes" />
app:layout_constraintTop_toBottomOf="@id/cbFileNames" />
<CheckBox
android:id="@+id/cbHtml"
@ -583,7 +594,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
app:constraint_referenced_ids="
cbSearchIndex,tvSearchIndexHint,cbSenders,cbRecipients,cbSubject,cbKeywords,cbMessage,tvSearchTextHint,tvSearchTextUnsupported,cbNotes,
cbSearchIndex,tvSearchIndexHint,cbSenders,cbRecipients,cbSubject,cbKeywords,cbMessage,tvSearchTextHint,tvSearchTextUnsupported,cbNotes,cbFileNames,
tvAnd,cbUnseen,cbFlagged,cbHidden,cbEncrypted,cbAttachments,
tvDate,btnAfter,btnBefore,tvBefore,tvAfter,cbSearchDevice" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1805,6 +1805,7 @@
<string name="title_search_in_keywords">In keywords (if supported)</string>
<string name="title_search_in_message">In message text</string>
<string name="title_search_in_notes">In local notes</string>
<string name="title_search_in_filenames">In filenames (on device only)</string>
<string name="title_search_in_headers" translatable="false">In headers</string>
<string name="title_search_in_html" translatable="false">In HTML</string>
<string name="title_search_with">Limit search to</string>