From 86de9be1152e25597d99c096a34db6e15ff404ac Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sat, 4 Apr 2020 02:00:56 +0200 Subject: [PATCH 1/4] add basic help-search controls --- AndroidManifest.xml | 5 ++++- res/menu/local_help.xml | 5 +++++ res/xml/search_localhelp.xml | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 res/xml/search_localhelp.xml diff --git a/AndroidManifest.xml b/AndroidManifest.xml index f86a2fb81..7fce1bbd7 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -265,7 +265,10 @@ + android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"> + + diff --git a/res/menu/local_help.xml b/res/menu/local_help.xml index 0b1800bb8..af044845a 100644 --- a/res/menu/local_help.xml +++ b/res/menu/local_help.xml @@ -2,6 +2,11 @@ + + diff --git a/res/xml/search_localhelp.xml b/res/xml/search_localhelp.xml new file mode 100644 index 000000000..32defe966 --- /dev/null +++ b/res/xml/search_localhelp.xml @@ -0,0 +1,4 @@ + + + From 4342b8fa96874aa73660e7b060db62403dced865 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sat, 4 Apr 2020 13:06:15 +0200 Subject: [PATCH 2/4] implement searching in local-help --- res/xml/search_localhelp.xml | 3 +- .../securesms/LocalHelpActivity.java | 44 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/res/xml/search_localhelp.xml b/res/xml/search_localhelp.xml index 32defe966..b4f16fd0e 100644 --- a/res/xml/search_localhelp.xml +++ b/res/xml/search_localhelp.xml @@ -1,4 +1,5 @@ + android:label="@string/app_name" + android:includeInGlobalSearch="false" /> diff --git a/src/org/thoughtcrime/securesms/LocalHelpActivity.java b/src/org/thoughtcrime/securesms/LocalHelpActivity.java index f7318b12a..fe5fd6347 100644 --- a/src/org/thoughtcrime/securesms/LocalHelpActivity.java +++ b/src/org/thoughtcrime/securesms/LocalHelpActivity.java @@ -12,6 +12,8 @@ import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; +import androidx.appcompat.widget.SearchView; + import org.thoughtcrime.securesms.connect.ApplicationDcContext; import org.thoughtcrime.securesms.connect.DcHelper; import org.thoughtcrime.securesms.util.DynamicLanguage; @@ -23,6 +25,8 @@ import java.util.Arrays; import java.util.Locale; public class LocalHelpActivity extends PassphraseRequiredActionBarActivity + implements SearchView.OnQueryTextListener, + WebView.FindListener { private WebView webView; private final DynamicTheme dynamicTheme = new DynamicTheme(); @@ -84,6 +88,7 @@ public class LocalHelpActivity extends PassphraseRequiredActionBarActivity } }); webView.loadUrl("file:///android_asset/" + helpPath.replace("LANG", helpLang)); + webView.setFindListener(this); } @Override @@ -104,10 +109,49 @@ public class LocalHelpActivity extends PassphraseRequiredActionBarActivity menu.clear(); inflater.inflate(R.menu.local_help, menu); + + MenuItem searchItem = menu.findItem(R.id.menu_search_localhelp); + SearchView searchView = (SearchView) searchItem.getActionView(); + searchView.setOnQueryTextListener(this); + super.onPrepareOptionsMenu(menu); return true; } + private String lastQuery = ""; + private Toast lastToast = null; + + @Override + public boolean onQueryTextSubmit(String query) { + webView.findNext(true); + return true; // action handled by listener + } + + @Override + public boolean onQueryTextChange(String query) { + String normQuery = query.trim(); + lastQuery = normQuery; + if (lastToast!=null) { + lastToast.cancel(); + lastToast = null; + } + webView.findAllAsync(normQuery); + return true; // action handled by listener + } + + @Override + public void onFindResultReceived (int activeMatchOrdinal, int numberOfMatches, boolean isDoneCounting) + { + if (isDoneCounting && numberOfMatches==0 && !lastQuery.isEmpty()) { + String msg = getString(R.string.search_no_result_for_x, lastQuery); + if (lastToast!=null) { + lastToast.cancel(); + } + lastToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT); + lastToast.show(); + } + } + @Override public boolean onOptionsItemSelected(MenuItem item) { super.onOptionsItemSelected(item); From 39bc508a313f9a983ee92d6ec6c0b4b7440f0939 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sat, 4 Apr 2020 14:09:53 +0200 Subject: [PATCH 3/4] remove unused search xml files --- AndroidManifest.xml | 2 -- res/xml/search_localhelp.xml | 5 ----- src/org/thoughtcrime/securesms/LocalHelpActivity.java | 5 +---- 3 files changed, 1 insertion(+), 11 deletions(-) delete mode 100644 res/xml/search_localhelp.xml diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7fce1bbd7..ad500c2e8 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -266,8 +266,6 @@ - diff --git a/res/xml/search_localhelp.xml b/res/xml/search_localhelp.xml deleted file mode 100644 index b4f16fd0e..000000000 --- a/res/xml/search_localhelp.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/src/org/thoughtcrime/securesms/LocalHelpActivity.java b/src/org/thoughtcrime/securesms/LocalHelpActivity.java index fe5fd6347..6ec18f869 100644 --- a/src/org/thoughtcrime/securesms/LocalHelpActivity.java +++ b/src/org/thoughtcrime/securesms/LocalHelpActivity.java @@ -14,14 +14,10 @@ import android.widget.Toast; import androidx.appcompat.widget.SearchView; -import org.thoughtcrime.securesms.connect.ApplicationDcContext; -import org.thoughtcrime.securesms.connect.DcHelper; import org.thoughtcrime.securesms.util.DynamicLanguage; import org.thoughtcrime.securesms.util.DynamicTheme; -import java.io.File; import java.io.InputStream; -import java.util.Arrays; import java.util.Locale; public class LocalHelpActivity extends PassphraseRequiredActionBarActivity @@ -113,6 +109,7 @@ public class LocalHelpActivity extends PassphraseRequiredActionBarActivity MenuItem searchItem = menu.findItem(R.id.menu_search_localhelp); SearchView searchView = (SearchView) searchItem.getActionView(); searchView.setOnQueryTextListener(this); + searchView.setQueryHint(getString(R.string.search)); super.onPrepareOptionsMenu(menu); return true; From 62ee8530f2fa404aead79e8593e41fcda4e28091 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sat, 4 Apr 2020 16:28:14 +0200 Subject: [PATCH 4/4] add up/down buttons to search --- res/drawable-xhdpi/ic_search_down.png | Bin 0 -> 1823 bytes res/drawable-xhdpi/ic_search_up.png | Bin 0 -> 1831 bytes res/menu/local_help.xml | 12 ++++ .../securesms/BaseActionBarActivity.java | 14 +++++ .../securesms/LocalHelpActivity.java | 53 ++++++++++++++++-- 5 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 res/drawable-xhdpi/ic_search_down.png create mode 100644 res/drawable-xhdpi/ic_search_up.png diff --git a/res/drawable-xhdpi/ic_search_down.png b/res/drawable-xhdpi/ic_search_down.png new file mode 100644 index 0000000000000000000000000000000000000000..23e4d7c4f20ea277fbb224475149fbb499bb13fc GIT binary patch literal 1823 zcmV+)2jKXLP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|uj_fE5{O?oj5wHyyj>D()Zm`GSBFS|3^khcU zd9%{4^g?$a4k=8PaR`mSe@*%ehh&Z9gQb{bbU1wWSqd7-?Z;lT^V@kl^tgrVcXqnn z5SaAdGmfKwfj!(GFn`$VdplV>aMA&E+;{`jHL{@54<`>GmEF$AHD%cwB|c2&_^WLY zx6aSk-atkVFshIYWp&$G_K|e|7ySKxMn~3wc2L8a^@KmVQFlV%t@Xs8YlmI$bnHNH z(~3_#9d-`q{B0~fdc<-YSspzCPH~UN1AlY&H0Ri7S3Ke<`*=+1Z7N#}9V_V6?Xier z_y@FYD;XtWm;(D;3!XT#O<4rtC5=FBeLxPo7@;tOsp<<=R! zAPCQc)3EW&v{&x=Si&k43>(b}6D+Ro5H;{Uwsg~3T_AMzZV!33egJ?Xj2++%D->`M zfz6Sfi5N3@Owgymb3xcwD8PY&ba*LVHA0*uYivAYy!DkJyBX;PLIjOiBnbi)h~<6o z5$i1>gbD=>K7_ZEfbaM}1EDnh z2qO*~Y2;BRVr}a5Gt4+`rkQ8CsdlLPUbScCzE+J7)npTD^|QNbFq^$W@Jc6PX$Hl_ zGZeR_00LT;W-hV!vXonzxhzVmLEvRr;&fh$K|w!Q!sMHFcjZ3Sjlk}!y2+Vxw50n9 zrAZvxek5i+^i96pbT z*VK$0vQC7HUyETP!&=|2s}f$9EoS zhXVT!^nEtY$)MNSI46T%XXCu4>#V#dgI;IjoD8~}HlE3#t7+p>8u?CW(ABi@Oa@&| z8_#6W&n%D+K-U)vT}>O$WYE>L@#AUajSRY)HlE3#YiYysaAl^dWm>|pF%$NOT}D^m zb8$Hi#>PFDQPg5|4VzSR8f!^yebdAl)@-VSGczYp$q*Q~Hr4P^+VKfHup94d+=kuk zsmY_Gx5XXL#KM_+64 zeK`7#wBLcF??=klaP(^6eFjI@;`k#R{m!y@grf^_Jhnu$`k>BYx!A^0Pa&dn=OEo$ zCy|;0ezAtsdq~ycGqw@;Hkx91?Z_uJ>A(4={R8xW z1X}MW`Uk=D;(I)*3-Hyr+t!#V$d zZ=hqRQC4+#Aj|90^#{RaaAhyO(bd;u7dwoqV&Hivw4TpbETb=dmURu_gFEH-R*{VbhEKc40`t4V%wZu+V%T#h-# z!)C;k2`M#wX|B!@4tr9Ul8}2UB56vZ-b^z!H=;^TE(fBaNVjRp+idbYrHte;k(Wuh zBa^4e!~EaxwU4uA)7qF9VHq~91yyG}hWAJ41+exEE7vVq%fH{&GUGHe|9s;Y_FqtJ z{J^tf00002VoOIv0RHfZ{3!qc010qNS#tmY3ljhU3ljkVnw%H_000McNliruvq zjPdIQjS9t&c N002ovPDHLkV1haYXH) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|uj_fE5{O?oj5x@p)j>D()Zm`GSBFS|3^khcU zd9%{4^g?$a4k=8PaR`mSe@*%e2WLqXqFTx+IUFH}%moc|`?1&Fh3&i@a@@l8J3HNO zFidjqna0t-z#i`pXgKWky`8ijICcOXH{Jkcjm&8D!^s0kc(?oGnlkT=k{+gW{6#m2 zTj%HNpdh117=?+4cyZgA_mO1(7yQG1Mn^9Z?I?<~7yHN`-KaYu@YZ_b&$YuYcRF^U zw`rv(o({W@=lpFfJ$mH%HZnhY1f1d?j|cwd>^A4vXIBE^D2H@R>TN1p3mq%ylD2xq)N z0hbWiK6$6i>OFWg=u_Z1BkU^_@R1^Sc*#K|K^)^XHl9(x_2tOB8R-Q=L`hgA27wC1 z3L%Ds^=1g6LQ!IfF{Y@|VvZ$A3MrUR5WPRq^hP_i-`q`mQ2koTgk|3NMn(5 z%9<_bTnYv)p#ZC(e}SQLl^SZSscN;FYiS6d7FuknX|tAF>D;9w1yE02yY<}5@B^VV z!iXac9X9eP6R|dBh8bs?I&J1zZmJ!szE|y8xvy38hibeDwfgB@HJDZ3ApA-vacKs{ zICvxWwsxDFy|@@EoVVX?IudQ{4#czN#CaDMw4X zpHPmLbPvjX)a^vIUbb{An?P$7f>UHj!SX|gVTG-%_tK@Bu0Hq&=)Vb6M@GoxrgMZm z5?)g?`Iu!QT*6um6B$CvN%DMsy#YwkUoT4kUL6(9Sy-3}ih36BI z4S#LjnDDpW{jEWDcXo4rxr^uFZccS1_l!@kvvE!az0SsYO|P?YP6oZs#yJ`EIveL? z&<_Rn9q9XPoRdMXvvE!az0SsYP1jj@PX@it#yJ^uHEleTL08kpr8M%L(4ebnui@y`!21l2uEp_3IQpGs@d!s3;&^O{X7xdxS#!~iqi!*wbN7+E zw&r6WYF!7nQTsp+!Y6R&i3An8ByY^sB7Uhx>pfa^_>67jdmBwKymaJ~YVvQsY5xHI zAA#2UiT(j`O5%fW&;vgJ00AOtLqkwWLqi~Na&Km7Y-Iodc$}S(u}Z^G6o$Xlq9S%u z9K<1mYe5h*xm1N9D8yL7=#(ZY7Lyo~l;RusCi*ZP1i>fp2^5_DZ**`li#HtpkHb0t ze{Y~;r%_gQcOc8_()9_(wX~|`)&Xg%)9xq@z~xnh45W$HaxNqweteAb1VWc1 z@<5tzHg{Od6FDHw*X$8w2_8uERrWio#kfUqK%9RId6wXSN0h%o^E1>$#GMC9Jk9x- z=uza>pu{leuj)L3P|rk + + + + diff --git a/src/org/thoughtcrime/securesms/BaseActionBarActivity.java b/src/org/thoughtcrime/securesms/BaseActionBarActivity.java index f82915532..f7595809b 100644 --- a/src/org/thoughtcrime/securesms/BaseActionBarActivity.java +++ b/src/org/thoughtcrime/securesms/BaseActionBarActivity.java @@ -9,6 +9,8 @@ import androidx.core.app.ActivityOptionsCompat; import androidx.appcompat.app.AppCompatActivity; import android.util.Log; import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.ViewConfiguration; import android.view.WindowManager; @@ -156,4 +158,16 @@ public abstract class BaseActionBarActivity extends AppCompatActivity { isWaitingForResult = true; } } + + public void makeSearchMenuVisible(final Menu menu, final MenuItem exception, boolean visible) { + for (int i = 0; i < menu.size(); ++i) { + MenuItem item = menu.getItem(i); + int id = item.getItemId(); + if (id==R.id.menu_search_up || id==R.id.menu_search_down) { + item.setVisible(!visible); + } else if (item != exception) { + item.setVisible(visible); + } + } + } } diff --git a/src/org/thoughtcrime/securesms/LocalHelpActivity.java b/src/org/thoughtcrime/securesms/LocalHelpActivity.java index 6ec18f869..cbf6b399a 100644 --- a/src/org/thoughtcrime/securesms/LocalHelpActivity.java +++ b/src/org/thoughtcrime/securesms/LocalHelpActivity.java @@ -5,11 +5,13 @@ import android.content.Intent; import android.content.res.AssetManager; import android.net.Uri; import android.os.Bundle; +import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.webkit.WebView; import android.webkit.WebViewClient; +import android.widget.ImageView; import android.widget.Toast; import androidx.appcompat.widget.SearchView; @@ -24,6 +26,8 @@ public class LocalHelpActivity extends PassphraseRequiredActionBarActivity implements SearchView.OnQueryTextListener, WebView.FindListener { + private static final String TAG = LocalHelpActivity.class.getSimpleName(); + private WebView webView; private final DynamicTheme dynamicTheme = new DynamicTheme(); private final DynamicLanguage dynamicLanguage = new DynamicLanguage(); @@ -106,10 +110,36 @@ public class LocalHelpActivity extends PassphraseRequiredActionBarActivity inflater.inflate(R.menu.local_help, menu); - MenuItem searchItem = menu.findItem(R.id.menu_search_localhelp); - SearchView searchView = (SearchView) searchItem.getActionView(); - searchView.setOnQueryTextListener(this); - searchView.setQueryHint(getString(R.string.search)); + try { + MenuItem searchItem = menu.findItem(R.id.menu_search_localhelp); + searchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() { + @Override + public boolean onMenuItemActionExpand(final MenuItem item) { + LocalHelpActivity.this.lastQuery = ""; + LocalHelpActivity.this.makeSearchMenuVisible(menu, searchItem, false); + return true; + } + + @Override + public boolean onMenuItemActionCollapse(final MenuItem item) { + LocalHelpActivity.this.makeSearchMenuVisible(menu, searchItem, true); + return true; + } + }); + SearchView searchView = (SearchView) searchItem.getActionView(); + searchView.setOnQueryTextListener(this); + searchView.setQueryHint(getString(R.string.search)); + searchView.setIconifiedByDefault(true); + + // hide the [X] beside the search field - this is too much noise, search can be aborted eg. by "back" + ImageView closeBtn = searchView.findViewById(R.id.search_close_btn); + if (closeBtn!=null) { + closeBtn.setEnabled(false); + closeBtn.setImageDrawable(null); + } + } catch (Exception e) { + Log.e(TAG, "cannot set up help-search: ", e); + } super.onPrepareOptionsMenu(menu); return true; @@ -120,7 +150,6 @@ public class LocalHelpActivity extends PassphraseRequiredActionBarActivity @Override public boolean onQueryTextSubmit(String query) { - webView.findNext(true); return true; // action handled by listener } @@ -156,6 +185,20 @@ public class LocalHelpActivity extends PassphraseRequiredActionBarActivity case android.R.id.home: finish(); return true; + case R.id.menu_search_up: + if (lastQuery.isEmpty()) { + webView.scrollTo(0, 0); + } else { + webView.findNext(false); + } + return true; + case R.id.menu_search_down: + if (lastQuery.isEmpty()) { + webView.scrollTo(0, 1000000000); + } else { + webView.findNext(true); + } + return true; case R.id.log_scroll_up: webView.scrollTo(0, 0); return true;