2020-04-09 15:50:29 +00:00
|
|
|
package eu.faircode.email;
|
|
|
|
|
2021-01-01 07:56:36 +00:00
|
|
|
/*
|
|
|
|
This file is part of FairEmail.
|
|
|
|
|
|
|
|
FairEmail 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.
|
|
|
|
|
|
|
|
FairEmail 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 FairEmail. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2022-01-01 08:46:36 +00:00
|
|
|
Copyright 2018-2022 by Marcel Bokhorst (M66B)
|
2021-01-01 07:56:36 +00:00
|
|
|
*/
|
|
|
|
|
2020-04-10 10:59:48 +00:00
|
|
|
import android.app.DatePickerDialog;
|
2020-04-09 15:50:29 +00:00
|
|
|
import android.app.Dialog;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.DialogInterface;
|
|
|
|
import android.content.SharedPreferences;
|
|
|
|
import android.database.Cursor;
|
|
|
|
import android.database.MatrixCursor;
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.text.TextUtils;
|
|
|
|
import android.view.KeyEvent;
|
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.View;
|
2020-05-03 15:13:52 +00:00
|
|
|
import android.view.WindowManager;
|
2020-04-09 15:50:29 +00:00
|
|
|
import android.view.inputmethod.EditorInfo;
|
2020-06-12 17:47:37 +00:00
|
|
|
import android.widget.AdapterView;
|
2020-04-10 10:59:48 +00:00
|
|
|
import android.widget.Button;
|
2020-04-09 15:50:29 +00:00
|
|
|
import android.widget.CheckBox;
|
|
|
|
import android.widget.CompoundButton;
|
2020-04-10 10:59:48 +00:00
|
|
|
import android.widget.DatePicker;
|
2020-04-09 15:50:29 +00:00
|
|
|
import android.widget.FilterQueryProvider;
|
2020-04-09 17:41:19 +00:00
|
|
|
import android.widget.ImageButton;
|
2020-06-12 16:49:46 +00:00
|
|
|
import android.widget.Spinner;
|
2020-04-09 15:50:29 +00:00
|
|
|
import android.widget.TextView;
|
|
|
|
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
import androidx.appcompat.app.AlertDialog;
|
2020-04-10 10:17:40 +00:00
|
|
|
import androidx.constraintlayout.widget.Group;
|
2020-04-09 15:50:29 +00:00
|
|
|
import androidx.cursoradapter.widget.SimpleCursorAdapter;
|
2021-09-28 06:27:02 +00:00
|
|
|
import androidx.lifecycle.Observer;
|
2020-04-09 15:50:29 +00:00
|
|
|
import androidx.preference.PreferenceManager;
|
|
|
|
|
2020-04-10 10:59:48 +00:00
|
|
|
import java.text.DateFormat;
|
2021-04-17 09:04:04 +00:00
|
|
|
import java.util.ArrayList;
|
2020-04-10 10:59:48 +00:00
|
|
|
import java.util.Calendar;
|
2020-08-09 15:18:06 +00:00
|
|
|
import java.util.List;
|
2020-04-10 10:59:48 +00:00
|
|
|
|
2021-06-14 06:10:00 +00:00
|
|
|
import io.requery.android.database.sqlite.SQLiteDatabase;
|
|
|
|
|
2020-04-09 15:50:29 +00:00
|
|
|
public class FragmentDialogSearch extends FragmentDialogBase {
|
2021-06-07 19:23:56 +00:00
|
|
|
private static final int MAX_SUGGESTIONS = 3;
|
|
|
|
|
2020-04-09 15:50:29 +00:00
|
|
|
@NonNull
|
|
|
|
@Override
|
|
|
|
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
2020-04-15 07:00:06 +00:00
|
|
|
final long account = getArguments().getLong("account", -1);
|
|
|
|
final long folder = getArguments().getLong("folder", -1);
|
|
|
|
|
2021-03-06 08:41:56 +00:00
|
|
|
final Context context = getContext();
|
|
|
|
boolean pro = ActivityBilling.isPro(context);
|
2020-04-15 07:00:06 +00:00
|
|
|
|
2021-03-06 08:41:56 +00:00
|
|
|
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
2020-04-15 07:00:06 +00:00
|
|
|
boolean fts = prefs.getBoolean("fts", false);
|
2021-09-28 06:26:40 +00:00
|
|
|
boolean last_fts = prefs.getBoolean("last_fts", true);
|
2020-04-15 07:00:06 +00:00
|
|
|
boolean last_search_senders = prefs.getBoolean("last_search_senders", true);
|
|
|
|
boolean last_search_recipients = prefs.getBoolean("last_search_recipients", true);
|
|
|
|
boolean last_search_subject = prefs.getBoolean("last_search_subject", true);
|
|
|
|
boolean last_search_keywords = prefs.getBoolean("last_search_keywords", false);
|
|
|
|
boolean last_search_message = prefs.getBoolean("last_search_message", true);
|
2021-02-28 15:12:48 +00:00
|
|
|
boolean last_search_notes = prefs.getBoolean("last_search_notes", true);
|
2021-06-16 16:14:45 +00:00
|
|
|
boolean last_search_trash = prefs.getBoolean("last_search_trash", true);
|
|
|
|
boolean last_search_junk = prefs.getBoolean("last_search_junk", true);
|
2020-04-15 07:00:06 +00:00
|
|
|
|
2021-03-06 08:41:56 +00:00
|
|
|
View dview = LayoutInflater.from(context).inflate(R.layout.dialog_search, null);
|
2020-04-09 15:50:29 +00:00
|
|
|
|
2021-09-25 07:37:17 +00:00
|
|
|
TextViewAutoCompleteAction etQuery = dview.findViewById(R.id.etQuery);
|
2022-01-16 11:35:45 +00:00
|
|
|
Button btnSearch1 = dview.findViewById(R.id.btnSearch1);
|
|
|
|
Button btnSearch2 = dview.findViewById(R.id.btnSearch2);
|
|
|
|
Button btnSearch3 = dview.findViewById(R.id.btnSearch3);
|
2021-09-25 07:37:17 +00:00
|
|
|
ImageButton ibResetSearches = dview.findViewById(R.id.ibResetSearches);
|
|
|
|
|
|
|
|
ImageButton ibInfo = dview.findViewById(R.id.ibInfo);
|
|
|
|
ImageButton ibFlagged = dview.findViewById(R.id.ibFlagged);
|
|
|
|
ImageButton ibUnseen = dview.findViewById(R.id.ibUnseen);
|
|
|
|
ImageButton ibInvite = dview.findViewById(R.id.ibInvite);
|
|
|
|
ImageButton ibAttachment = dview.findViewById(R.id.ibAttachment);
|
|
|
|
ImageButton ibNotes = dview.findViewById(R.id.ibNotes);
|
|
|
|
ImageButton ibMore = dview.findViewById(R.id.ibMore);
|
|
|
|
TextView tvMore = dview.findViewById(R.id.tvMore);
|
|
|
|
CheckBox cbSearchIndex = dview.findViewById(R.id.cbSearchIndex);
|
|
|
|
CheckBox cbSenders = dview.findViewById(R.id.cbSenders);
|
|
|
|
CheckBox cbRecipients = dview.findViewById(R.id.cbRecipients);
|
|
|
|
CheckBox cbSubject = dview.findViewById(R.id.cbSubject);
|
|
|
|
CheckBox cbKeywords = dview.findViewById(R.id.cbKeywords);
|
|
|
|
CheckBox cbMessage = dview.findViewById(R.id.cbMessage);
|
|
|
|
TextView tvSearchTextUnsupported = dview.findViewById(R.id.tvSearchTextUnsupported);
|
|
|
|
CheckBox cbNotes = dview.findViewById(R.id.cbNotes);
|
|
|
|
CheckBox cbHeaders = dview.findViewById(R.id.cbHeaders);
|
|
|
|
CheckBox cbHtml = dview.findViewById(R.id.cbHtml);
|
|
|
|
CheckBox cbSearchTrash = dview.findViewById(R.id.cbSearchTrash);
|
|
|
|
CheckBox cbSearchJunk = dview.findViewById(R.id.cbSearchJunk);
|
|
|
|
CheckBox cbUnseen = dview.findViewById(R.id.cbUnseen);
|
|
|
|
CheckBox cbFlagged = dview.findViewById(R.id.cbFlagged);
|
|
|
|
CheckBox cbHidden = dview.findViewById(R.id.cbHidden);
|
|
|
|
CheckBox cbEncrypted = dview.findViewById(R.id.cbEncrypted);
|
|
|
|
CheckBox cbAttachments = dview.findViewById(R.id.cbAttachments);
|
|
|
|
Spinner spMessageSize = dview.findViewById(R.id.spMessageSize);
|
|
|
|
Button btnBefore = dview.findViewById(R.id.btnBefore);
|
|
|
|
Button btnAfter = dview.findViewById(R.id.btnAfter);
|
|
|
|
TextView tvBefore = dview.findViewById(R.id.tvBefore);
|
|
|
|
TextView tvAfter = dview.findViewById(R.id.tvAfter);
|
|
|
|
Group grpMore = dview.findViewById(R.id.grpMore);
|
2020-04-09 15:50:29 +00:00
|
|
|
|
2020-04-09 18:45:29 +00:00
|
|
|
ibInfo.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
2021-04-27 14:40:27 +00:00
|
|
|
Helper.hideKeyboard(etQuery);
|
2020-11-11 16:35:32 +00:00
|
|
|
Helper.viewFAQ(v.getContext(), 13);
|
2020-04-09 18:45:29 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-04-09 15:50:29 +00:00
|
|
|
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
|
2021-03-06 08:41:56 +00:00
|
|
|
context,
|
2020-04-09 15:50:29 +00:00
|
|
|
R.layout.search_suggestion,
|
|
|
|
null,
|
|
|
|
new String[]{"suggestion"},
|
|
|
|
new int[]{android.R.id.text1},
|
|
|
|
0);
|
|
|
|
|
|
|
|
adapter.setFilterQueryProvider(new FilterQueryProvider() {
|
|
|
|
public Cursor runQuery(CharSequence typed) {
|
|
|
|
Log.i("Search suggest=" + typed);
|
|
|
|
|
|
|
|
MatrixCursor cursor = new MatrixCursor(new String[]{"_id", "suggestion"});
|
2021-04-17 07:15:17 +00:00
|
|
|
if (TextUtils.isEmpty(typed))
|
2020-04-09 15:50:29 +00:00
|
|
|
return cursor;
|
2021-06-14 06:10:00 +00:00
|
|
|
|
|
|
|
if (cbSearchIndex.isEnabled() && cbSearchIndex.isChecked()) {
|
|
|
|
SQLiteDatabase db = FtsDbHelper.getInstance(context);
|
|
|
|
List<String> suggestions = FtsDbHelper.getSuggestions(
|
|
|
|
db,
|
|
|
|
typed + "%",
|
|
|
|
MAX_SUGGESTIONS);
|
|
|
|
for (int i = 0; i < suggestions.size(); i++)
|
|
|
|
cursor.addRow(new Object[]{i + 1, suggestions.get(i)});
|
2021-06-14 04:15:30 +00:00
|
|
|
return cursor;
|
2021-06-14 06:10:00 +00:00
|
|
|
}
|
2020-04-09 15:50:29 +00:00
|
|
|
|
2021-03-06 08:41:56 +00:00
|
|
|
DB db = DB.getInstance(context);
|
2020-04-15 07:00:06 +00:00
|
|
|
return db.message().getSuggestions(
|
|
|
|
account < 0 ? null : account,
|
|
|
|
folder < 0 ? null : folder,
|
2021-06-14 06:10:00 +00:00
|
|
|
"%" + typed + "%",
|
2021-06-07 19:23:56 +00:00
|
|
|
MAX_SUGGESTIONS);
|
2020-04-09 15:50:29 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-04-09 18:24:35 +00:00
|
|
|
adapter.setCursorToStringConverter(new SimpleCursorAdapter.CursorToStringConverter() {
|
|
|
|
@Override
|
|
|
|
public CharSequence convertToString(Cursor cursor) {
|
2021-08-06 08:25:24 +00:00
|
|
|
int colSuggestion = cursor.getColumnIndex("suggestion");
|
|
|
|
return cursor.getString(colSuggestion);
|
2020-04-09 18:24:35 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-07-01 10:20:46 +00:00
|
|
|
etQuery.setActionRunnable(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
etQuery.setText(null);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
etQuery.setActionEnabled(true);
|
|
|
|
|
2020-04-09 15:50:29 +00:00
|
|
|
etQuery.setAdapter(adapter);
|
|
|
|
|
2021-04-17 09:04:04 +00:00
|
|
|
View.OnClickListener onSearch = new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
etQuery.setText(((TextView) v).getText());
|
|
|
|
((AlertDialog) getDialog()).getButton(DialogInterface.BUTTON_POSITIVE).performClick();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-01-16 11:35:45 +00:00
|
|
|
Button[] btn = new Button[]{btnSearch1, btnSearch2, btnSearch3};
|
2022-01-16 12:29:43 +00:00
|
|
|
|
|
|
|
int searches = 0;
|
|
|
|
for (int i = 0; i < btn.length; i++)
|
|
|
|
if (prefs.contains("last_search" + (i + 1)))
|
|
|
|
searches++;
|
|
|
|
|
|
|
|
for (int i = 0; i < btn.length; i++) {
|
|
|
|
if (prefs.contains("last_search" + (i + 1))) {
|
|
|
|
String search = prefs.getString("last_search" + (i + 1), null);
|
|
|
|
btn[i].setText(search);
|
|
|
|
btn[i].setOnClickListener(onSearch);
|
|
|
|
btn[i].setVisibility(View.VISIBLE);
|
|
|
|
} else
|
|
|
|
btn[i].setVisibility(searches > 0 ? View.INVISIBLE : View.GONE);
|
2021-04-17 09:04:04 +00:00
|
|
|
}
|
2022-01-16 12:29:43 +00:00
|
|
|
|
|
|
|
ibResetSearches.setVisibility(searches > 0 ? View.VISIBLE : View.GONE);
|
2021-04-17 09:04:04 +00:00
|
|
|
|
|
|
|
ibResetSearches.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
SharedPreferences.Editor editor = prefs.edit();
|
|
|
|
for (int i = 1; i <= 3; i++) {
|
|
|
|
editor.remove("last_search" + i);
|
2022-01-16 11:35:45 +00:00
|
|
|
btn[i - 1].setVisibility(View.GONE);
|
2021-04-17 09:04:04 +00:00
|
|
|
}
|
|
|
|
editor.apply();
|
|
|
|
ibResetSearches.setVisibility(View.GONE);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-04-10 10:17:40 +00:00
|
|
|
View.OnClickListener onMore = new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
2021-04-27 14:40:27 +00:00
|
|
|
Helper.hideKeyboard(etQuery);
|
2020-04-10 10:17:40 +00:00
|
|
|
|
|
|
|
if (grpMore.getVisibility() == View.VISIBLE) {
|
|
|
|
ibMore.setImageLevel(1);
|
|
|
|
grpMore.setVisibility(View.GONE);
|
2021-04-27 06:51:32 +00:00
|
|
|
cbHeaders.setVisibility(View.GONE);
|
2021-04-27 07:12:10 +00:00
|
|
|
cbHtml.setVisibility(View.GONE);
|
2021-06-16 16:14:45 +00:00
|
|
|
cbSearchTrash.setVisibility(View.GONE);
|
|
|
|
cbSearchJunk.setVisibility(View.GONE);
|
2020-04-10 10:17:40 +00:00
|
|
|
} else {
|
|
|
|
ibMore.setImageLevel(0);
|
|
|
|
grpMore.setVisibility(View.VISIBLE);
|
2021-04-27 07:12:10 +00:00
|
|
|
if (BuildConfig.DEBUG) {
|
2021-04-27 06:51:32 +00:00
|
|
|
cbHeaders.setVisibility(View.VISIBLE);
|
2021-04-27 07:12:10 +00:00
|
|
|
cbHtml.setVisibility(View.VISIBLE);
|
|
|
|
}
|
2021-06-17 12:58:57 +00:00
|
|
|
if (folder < 0) {
|
2021-06-16 16:14:45 +00:00
|
|
|
cbSearchTrash.setVisibility(View.VISIBLE);
|
|
|
|
cbSearchJunk.setVisibility(View.VISIBLE);
|
|
|
|
}
|
2020-04-10 10:17:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
ibMore.setOnClickListener(onMore);
|
|
|
|
tvMore.setOnClickListener(onMore);
|
|
|
|
|
2020-04-09 15:50:29 +00:00
|
|
|
cbSearchIndex.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
|
|
@Override
|
|
|
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
2021-09-28 06:26:40 +00:00
|
|
|
prefs.edit().putBoolean("last_fts", isChecked).apply();
|
2021-04-27 06:51:32 +00:00
|
|
|
cbHeaders.setEnabled(!isChecked);
|
2021-04-27 07:12:10 +00:00
|
|
|
cbHtml.setEnabled(!isChecked);
|
2020-04-09 15:50:29 +00:00
|
|
|
cbAttachments.setEnabled(!isChecked);
|
2020-06-12 16:49:46 +00:00
|
|
|
spMessageSize.setEnabled(!isChecked);
|
2020-04-09 15:50:29 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-04-09 18:45:29 +00:00
|
|
|
cbSenders.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
|
|
@Override
|
|
|
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
|
|
prefs.edit().putBoolean("last_search_senders", isChecked).apply();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
cbRecipients.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
|
|
@Override
|
|
|
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
|
|
prefs.edit().putBoolean("last_search_recipients", isChecked).apply();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
cbSubject.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
|
|
@Override
|
|
|
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
|
|
prefs.edit().putBoolean("last_search_subject", isChecked).apply();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
cbKeywords.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
|
|
@Override
|
|
|
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
|
|
prefs.edit().putBoolean("last_search_keywords", isChecked).apply();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
cbMessage.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
|
|
@Override
|
|
|
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
|
|
prefs.edit().putBoolean("last_search_message", isChecked).apply();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-02-28 15:12:48 +00:00
|
|
|
cbNotes.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
|
|
@Override
|
|
|
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
|
|
prefs.edit().putBoolean("last_search_notes", isChecked).apply();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-06-18 15:44:37 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-06-12 17:47:37 +00:00
|
|
|
spMessageSize.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
|
|
|
@Override
|
|
|
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
|
|
|
parent.post(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2020-06-20 07:43:54 +00:00
|
|
|
//parent.requestFocusFromTouch();
|
2020-06-12 17:47:37 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onNothingSelected(AdapterView<?> parent) {
|
|
|
|
// Do nothing
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-04-10 10:59:48 +00:00
|
|
|
btnAfter.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
pickDate(tvAfter);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
btnBefore.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
pickDate(tvBefore);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-04-10 10:17:40 +00:00
|
|
|
ibMore.setImageLevel(1);
|
2021-09-28 06:26:40 +00:00
|
|
|
cbSearchIndex.setChecked(last_fts && fts && pro);
|
|
|
|
cbSearchIndex.setEnabled(fts && pro);
|
2020-04-09 18:45:29 +00:00
|
|
|
cbSenders.setChecked(last_search_senders);
|
|
|
|
cbRecipients.setChecked(last_search_recipients);
|
|
|
|
cbSubject.setChecked(last_search_subject);
|
|
|
|
cbKeywords.setChecked(last_search_keywords);
|
|
|
|
cbMessage.setChecked(last_search_message);
|
2021-08-07 10:22:41 +00:00
|
|
|
tvSearchTextUnsupported.setText(getString(R.string.title_search_text_unsupported,
|
2021-09-08 18:36:18 +00:00
|
|
|
"full text search not supported"));
|
2021-02-28 15:12:48 +00:00
|
|
|
cbNotes.setChecked(last_search_notes);
|
2020-04-10 10:59:48 +00:00
|
|
|
tvAfter.setText(null);
|
|
|
|
tvBefore.setText(null);
|
2021-06-16 16:14:45 +00:00
|
|
|
cbSearchTrash.setChecked(last_search_trash);
|
|
|
|
cbSearchJunk.setChecked(last_search_junk);
|
2020-04-09 15:50:29 +00:00
|
|
|
|
2020-04-10 10:17:40 +00:00
|
|
|
grpMore.setVisibility(View.GONE);
|
2021-04-27 06:51:32 +00:00
|
|
|
cbHeaders.setVisibility(View.GONE);
|
2021-04-27 07:12:10 +00:00
|
|
|
cbHtml.setVisibility(View.GONE);
|
2021-06-16 16:14:45 +00:00
|
|
|
cbSearchTrash.setVisibility(View.GONE);
|
|
|
|
cbSearchJunk.setVisibility(View.GONE);
|
2020-04-10 10:17:40 +00:00
|
|
|
|
2021-03-06 08:41:56 +00:00
|
|
|
final AlertDialog dialog = new AlertDialog.Builder(context)
|
2020-04-09 15:50:29 +00:00
|
|
|
.setView(dview)
|
|
|
|
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
2021-09-25 07:37:17 +00:00
|
|
|
BoundaryCallbackMessages.SearchCriteria criteria = new BoundaryCallbackMessages.SearchCriteria();
|
|
|
|
|
|
|
|
criteria.query = etQuery.getText().toString().trim();
|
|
|
|
if (TextUtils.isEmpty(criteria.query))
|
|
|
|
criteria.query = null;
|
|
|
|
|
|
|
|
criteria.fts = cbSearchIndex.isChecked();
|
2021-10-11 13:15:25 +00:00
|
|
|
criteria.in_senders = cbSenders.isChecked();
|
|
|
|
criteria.in_recipients = cbRecipients.isChecked();
|
|
|
|
criteria.in_subject = cbSubject.isChecked();
|
|
|
|
criteria.in_keywords = cbKeywords.isChecked();
|
|
|
|
criteria.in_message = cbMessage.isChecked();
|
|
|
|
criteria.in_notes = cbNotes.isChecked();
|
|
|
|
criteria.in_headers = (!criteria.fts && cbHeaders.isChecked());
|
|
|
|
criteria.in_html = (!criteria.fts && cbHtml.isChecked());
|
|
|
|
criteria.with_unseen = cbUnseen.isChecked();
|
|
|
|
criteria.with_flagged = cbFlagged.isChecked();
|
|
|
|
criteria.with_hidden = cbHidden.isChecked();
|
|
|
|
criteria.with_encrypted = cbEncrypted.isChecked();
|
|
|
|
criteria.with_attachments = (!criteria.fts && cbAttachments.isChecked());
|
2021-09-25 07:37:17 +00:00
|
|
|
|
2021-10-11 13:15:25 +00:00
|
|
|
if (!criteria.fts) {
|
2021-09-25 07:37:17 +00:00
|
|
|
int pos = spMessageSize.getSelectedItemPosition();
|
|
|
|
if (pos > 0) {
|
|
|
|
int[] sizes = getResources().getIntArray(R.array.sizeValues);
|
|
|
|
criteria.with_size = sizes[pos];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
criteria.in_trash = cbSearchTrash.isChecked();
|
|
|
|
criteria.in_junk = cbSearchJunk.isChecked();
|
|
|
|
|
|
|
|
Object after = tvAfter.getTag();
|
|
|
|
Object before = tvBefore.getTag();
|
|
|
|
|
|
|
|
if (after != null)
|
|
|
|
criteria.after = ((Calendar) after).getTimeInMillis();
|
|
|
|
if (before != null)
|
|
|
|
criteria.before = ((Calendar) before).getTimeInMillis();
|
2021-04-17 09:04:04 +00:00
|
|
|
|
2021-09-24 11:36:06 +00:00
|
|
|
if (criteria.query != null) {
|
2021-04-17 09:04:04 +00:00
|
|
|
List<String> searches = new ArrayList<>();
|
|
|
|
for (int i = 1; i <= 3; i++)
|
|
|
|
if (prefs.contains("last_search" + i)) {
|
|
|
|
String search = prefs.getString("last_search" + i, null);
|
|
|
|
searches.add(search);
|
|
|
|
}
|
|
|
|
|
2022-01-17 06:48:46 +00:00
|
|
|
searches.remove(criteria.query);
|
|
|
|
searches.add(0, criteria.query);
|
2021-04-17 09:04:04 +00:00
|
|
|
|
|
|
|
SharedPreferences.Editor editor = prefs.edit();
|
|
|
|
for (int i = 1; i <= Math.min(3, searches.size()); i++)
|
|
|
|
editor.putString("last_search" + i, searches.get(i - 1));
|
|
|
|
editor.apply();
|
|
|
|
}
|
2021-04-05 07:28:44 +00:00
|
|
|
|
2021-04-27 14:40:27 +00:00
|
|
|
Helper.hideKeyboard(etQuery);
|
2020-04-09 17:41:19 +00:00
|
|
|
|
2020-08-09 15:18:06 +00:00
|
|
|
if (criteria.query != null && criteria.query.startsWith("raw:"))
|
|
|
|
new SimpleTask<EntityFolder>() {
|
|
|
|
@Override
|
2020-09-08 18:54:48 +00:00
|
|
|
protected EntityFolder onExecute(Context context, Bundle args) {
|
2020-08-09 15:18:06 +00:00
|
|
|
long aid = args.getLong("account", -1);
|
|
|
|
|
|
|
|
DB db = DB.getInstance(context);
|
|
|
|
EntityAccount account = null;
|
|
|
|
if (aid < 0) {
|
2022-01-27 13:43:55 +00:00
|
|
|
List<EntityAccount> accounts = db.account().getSynchronizingAccounts(EntityAccount.TYPE_IMAP);
|
2020-08-09 15:18:06 +00:00
|
|
|
if (accounts == null)
|
|
|
|
return null;
|
|
|
|
for (EntityAccount a : accounts)
|
|
|
|
if (a.isGmail())
|
|
|
|
if (account == null)
|
|
|
|
account = a;
|
|
|
|
else
|
|
|
|
return null;
|
|
|
|
} else
|
|
|
|
account = db.account().getAccount(aid);
|
|
|
|
|
|
|
|
if (account == null || !account.isGmail())
|
|
|
|
return null;
|
|
|
|
|
|
|
|
return db.folder().getFolderByType(account.id, EntityFolder.ARCHIVE);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onExecuted(Bundle args, EntityFolder archive) {
|
|
|
|
FragmentMessages.search(
|
2021-03-06 08:41:56 +00:00
|
|
|
context, getViewLifecycleOwner(), getParentFragmentManager(),
|
2020-08-09 15:18:06 +00:00
|
|
|
account,
|
|
|
|
archive == null ? folder : archive.id,
|
|
|
|
archive != null,
|
|
|
|
criteria);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onException(Bundle args, Throwable ex) {
|
2021-02-18 17:50:51 +00:00
|
|
|
Log.e(ex);
|
2020-08-09 15:18:06 +00:00
|
|
|
}
|
2021-03-06 08:41:56 +00:00
|
|
|
}.execute(context, getViewLifecycleOwner(), getArguments(), "search:raw");
|
2020-08-09 15:18:06 +00:00
|
|
|
else
|
|
|
|
FragmentMessages.search(
|
2021-03-06 08:41:56 +00:00
|
|
|
context, getViewLifecycleOwner(), getParentFragmentManager(),
|
2020-08-09 15:18:06 +00:00
|
|
|
account, folder, false, criteria);
|
2020-04-09 15:50:29 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
|
|
// Do nothing
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.create();
|
|
|
|
|
2020-05-02 18:53:49 +00:00
|
|
|
View.OnClickListener onClick = new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
dialog.dismiss();
|
|
|
|
|
|
|
|
BoundaryCallbackMessages.SearchCriteria criteria = new BoundaryCallbackMessages.SearchCriteria();
|
2021-02-05 10:15:02 +00:00
|
|
|
int id = v.getId();
|
2021-03-27 09:01:55 +00:00
|
|
|
if (id == R.id.ibFlagged)
|
|
|
|
criteria.with_flagged = true;
|
|
|
|
else if (id == R.id.ibUnseen)
|
|
|
|
criteria.with_unseen = true;
|
2021-03-25 13:02:12 +00:00
|
|
|
else if (id == R.id.ibInvite) {
|
2021-02-05 10:15:02 +00:00
|
|
|
criteria.with_attachments = true;
|
|
|
|
criteria.with_types = new String[]{"text/calendar"};
|
2021-03-27 09:01:55 +00:00
|
|
|
} else if (id == R.id.ibAttachment)
|
|
|
|
criteria.with_attachments = true;
|
|
|
|
else if (id == R.id.ibNotes)
|
|
|
|
criteria.with_notes = true;
|
2020-05-02 18:53:49 +00:00
|
|
|
|
|
|
|
FragmentMessages.search(
|
2021-03-06 08:41:56 +00:00
|
|
|
context, getViewLifecycleOwner(), getParentFragmentManager(),
|
2020-05-02 18:53:49 +00:00
|
|
|
account, folder, false, criteria);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-03-25 13:02:12 +00:00
|
|
|
ibNotes.setOnClickListener(onClick);
|
2020-07-06 07:28:56 +00:00
|
|
|
ibAttachment.setOnClickListener(onClick);
|
2021-03-27 09:01:55 +00:00
|
|
|
ibInvite.setOnClickListener(onClick);
|
2020-05-02 18:53:49 +00:00
|
|
|
ibUnseen.setOnClickListener(onClick);
|
|
|
|
ibFlagged.setOnClickListener(onClick);
|
|
|
|
|
2020-04-09 15:50:29 +00:00
|
|
|
etQuery.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
|
|
|
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
2021-08-06 08:29:20 +00:00
|
|
|
if (actionId == EditorInfo.IME_ACTION_GO ||
|
2021-09-08 18:36:18 +00:00
|
|
|
(event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
|
2020-04-09 15:50:29 +00:00
|
|
|
dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-09-28 06:27:02 +00:00
|
|
|
DB db = DB.getInstance(context);
|
|
|
|
db.message().liveFts().observe(getViewLifecycleOwner(), new Observer<TupleFtsStats>() {
|
|
|
|
private TupleFtsStats last = null;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onChanged(TupleFtsStats stats) {
|
|
|
|
if (stats == null)
|
|
|
|
cbSearchIndex.setText(R.string.title_search_use_index);
|
|
|
|
else if (last == null || !last.equals(stats)) {
|
|
|
|
int perc = (int) (100 * stats.fts / (float) stats.total);
|
|
|
|
cbSearchIndex.setText(getString(R.string.title_name_count,
|
|
|
|
getString(R.string.title_search_use_index), perc + "%"));
|
|
|
|
}
|
|
|
|
last = stats;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-04-09 15:50:29 +00:00
|
|
|
return dialog;
|
|
|
|
}
|
2020-04-10 10:59:48 +00:00
|
|
|
|
2021-04-29 07:46:50 +00:00
|
|
|
@Override
|
|
|
|
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
|
|
|
super.onActivityCreated(savedInstanceState);
|
|
|
|
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
|
|
|
}
|
|
|
|
|
2020-05-03 15:13:52 +00:00
|
|
|
@Override
|
|
|
|
public void onDismiss(@NonNull DialogInterface dialog) {
|
|
|
|
super.onDismiss(dialog);
|
|
|
|
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
|
|
|
|
}
|
|
|
|
|
2020-04-10 10:59:48 +00:00
|
|
|
private void pickDate(TextView tv) {
|
|
|
|
Object tag = tv.getTag();
|
|
|
|
final Calendar cal = (tag == null ? Calendar.getInstance() : (Calendar) tag);
|
|
|
|
|
2020-10-30 09:36:16 +00:00
|
|
|
DatePickerDialog picker = new DatePickerDialog(getContext(),
|
2020-04-10 10:59:48 +00:00
|
|
|
new DatePickerDialog.OnDateSetListener() {
|
|
|
|
@Override
|
|
|
|
public void onDateSet(DatePicker view, int year, int month, int day) {
|
|
|
|
cal.set(Calendar.YEAR, year);
|
|
|
|
cal.set(Calendar.MONTH, month);
|
|
|
|
cal.set(Calendar.DAY_OF_MONTH, day);
|
|
|
|
|
2020-10-30 09:36:16 +00:00
|
|
|
DateFormat DF = Helper.getDateInstance(getContext());
|
2020-04-10 10:59:48 +00:00
|
|
|
|
|
|
|
tv.setTag(cal);
|
|
|
|
tv.setText(DF.format(cal.getTime()));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH));
|
|
|
|
|
|
|
|
picker.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
|
|
|
@Override
|
|
|
|
public void onCancel(DialogInterface dialog) {
|
|
|
|
tv.setTag(null);
|
|
|
|
tv.setText(null);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
picker.show();
|
|
|
|
}
|
2020-04-09 15:50:29 +00:00
|
|
|
}
|