Skip to content

Commit da66be3

Browse files
committed
Binary search - 3
1 parent 15940b4 commit da66be3

13 files changed

Lines changed: 205 additions & 62 deletions

File tree

app/src/main/java/org/exbin/bined/editor/android/MainActivity.java

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import android.text.method.TextKeyListener;
3636
import android.view.ContextMenu;
3737
import android.view.KeyEvent;
38+
import android.view.LayoutInflater;
3839
import android.view.Menu;
3940
import android.view.MenuItem;
4041
import android.view.View;
@@ -43,6 +44,7 @@
4344
import android.widget.Button;
4445
import android.widget.EditText;
4546
import android.widget.LinearLayout;
47+
import android.widget.TextView;
4648
import android.widget.Toast;
4749

4850
import androidx.activity.result.ActivityResult;
@@ -98,6 +100,7 @@
98100
import org.exbin.bined.editor.android.search.SearchParameters;
99101
import org.exbin.bined.highlight.android.NonAsciiCodeAreaColorAssessor;
100102
import org.exbin.bined.highlight.android.NonprintablesCodeAreaAssessor;
103+
import org.exbin.bined.highlight.android.SearchCodeAreaColorAssessor;
101104
import org.exbin.bined.operation.android.CodeAreaOperationCommandHandler;
102105
import org.exbin.bined.operation.undo.BinaryDataUndoRedoChangeListener;
103106
import org.exbin.framework.bined.BinEdCodeAreaAssessor;
@@ -150,23 +153,29 @@ public class MainActivity extends AppCompatActivity implements FileDialog.OnFile
150153
private final BinaryStatusHandler binaryStatus = new BinaryStatusHandler(this);
151154
private BinarySearch binarySearch;
152155
private SearchParameters searchParameters = null;
156+
private View searchStatusPanel;
153157
private Runnable postSaveAsAction = null;
154158
private boolean keyboardShown = false;
155159
private boolean dataInspectorShown = true;
156160
private long lastBackKeyPressTime = -1;
157161
private long lastReleaseBackKeyPressTime = -1;
158-
BasicValuesPositionColorModifier basicValuesPositionColorModifier = new BasicValuesPositionColorModifier();
162+
private BasicValuesPositionColorModifier basicValuesPositionColorModifier = new BasicValuesPositionColorModifier();
159163
private FallbackFileType fallbackFileType = FallbackFileType.FILE;
160164

161165
private final BinarySearchService.SearchStatusListener searchStatusListener = new BinarySearchService.SearchStatusListener() {
162166
@Override
163167
public void setStatus(BinarySearchService.FoundMatches foundMatches, SearchParameters.MatchMode matchMode) {
164-
// TODO Add search status panel
168+
runOnUiThread(() -> {
169+
showSearchStatusPanel();
170+
updateSearchStatusPanel(foundMatches.getMatchPosition(), foundMatches.getMatchesCount());
171+
});
165172
}
166173

167174
@Override
168175
public void clearStatus() {
169-
176+
runOnUiThread(() -> {
177+
hideSearchStatusPanel();
178+
});
170179
}
171180
};
172181
private final BinaryDataUndoRedoChangeListener codeAreaChangeListener = () -> {
@@ -228,6 +237,8 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
228237

229238
toolbar = findViewById(R.id.toolbar);
230239
keyPanel = findViewById(R.id.keyPanel);
240+
LayoutInflater inflater = getLayoutInflater();
241+
searchStatusPanel = inflater.inflate(R.layout.search_panel, null);
231242
basicValuesInspectorView = findViewById(R.id.basic_values_inspector);
232243
setSupportActionBar(toolbar);
233244

@@ -298,7 +309,12 @@ private void setupKeyPanel(KeysPanelMode keysPanelMode) {
298309
}
299310

300311
if (keyPanelIndex == -1) {
301-
mainView.addView(keyPanel, 2);
312+
int searchStatusPanelIndex = mainView.indexOfChild(searchStatusPanel);
313+
if (searchStatusPanelIndex >= 0) {
314+
mainView.addView(keyPanel, 2);
315+
} else {
316+
mainView.addView(keyPanel, searchStatusPanelIndex + 1);
317+
}
302318
mainView.requestLayout();
303319
}
304320

@@ -402,6 +418,48 @@ private void setupKeyPanelSize(int buttonWidth, int buttonHeight) {
402418
buttonTab.setMinHeight(buttonHeight);
403419
}
404420

421+
private void showSearchStatusPanel() {
422+
LinearLayout mainView = findViewById(R.id.main);
423+
int searchStatusPanelIndex = mainView.indexOfChild(searchStatusPanel);
424+
if (searchStatusPanelIndex == -1) {
425+
TextView searchStatus = searchStatusPanel.findViewById(R.id.searchStatus);
426+
Button prevButton = searchStatusPanel.findViewById(R.id.previousMatchButton);
427+
prevButton.setEnabled(false);
428+
Button nextButton = searchStatusPanel.findViewById(R.id.nextMatchButton);
429+
nextButton.setEnabled(false);
430+
431+
Resources resources = getResources();
432+
searchStatus.setText(resources.getString(R.string.search_in_progress));
433+
434+
mainView.addView(searchStatusPanel, 2);
435+
}
436+
}
437+
438+
private void hideSearchStatusPanel() {
439+
LinearLayout mainView = findViewById(R.id.main);
440+
int searchStatusPanelIndex = mainView.indexOfChild(searchStatusPanel);
441+
if (searchStatusPanelIndex >= 0) {
442+
mainView.removeViewAt(searchStatusPanelIndex);
443+
}
444+
}
445+
446+
private void updateSearchStatusPanel(int matchPosition, int matchesCount) {
447+
TextView searchStatus = searchStatusPanel.findViewById(R.id.searchStatus);
448+
Button prevButton = searchStatusPanel.findViewById(R.id.previousMatchButton);
449+
prevButton.setEnabled(matchPosition > 0 && matchesCount > 0);
450+
Button nextButton = searchStatusPanel.findViewById(R.id.nextMatchButton);
451+
nextButton.setEnabled(matchPosition < matchesCount - 1 && matchesCount > 0);
452+
453+
Resources resources = getResources();
454+
if (matchesCount == 1) {
455+
searchStatus.setText(resources.getString(R.string.search_match_single));
456+
} else if (matchesCount > 0) {
457+
searchStatus.setText(String.format(resources.getString(R.string.search_match_found), matchPosition + 1, matchesCount));
458+
} else {
459+
searchStatus.setText(resources.getString(R.string.search_match_none));
460+
}
461+
}
462+
405463
@Override
406464
protected void onDestroy() {
407465
super.onDestroy();
@@ -568,6 +626,7 @@ public boolean onContextItemSelected(MenuItem item) {
568626
switch (item.getItemId()) {
569627
case GO_TO_SIDE_PANEL_POPUP_ID: {
570628
LinearLayout mainView = findViewById(R.id.main);
629+
int searchStatusPanelIndex = mainView.indexOfChild(searchStatusPanel);
571630
int keyPanelIndex = mainView.indexOfChild(keyPanel);
572631
if (keyPanelIndex >= 0) {
573632
View downButton = findViewById(R.id.buttonDown);
@@ -875,8 +934,12 @@ public boolean onOptionsItemSelected(MenuItem item) {
875934
searchDialog.setBinarySearch(binarySearch);
876935
searchDialog.setSearchParameters(searchParameters);
877936
searchDialog.setTemplateCodeArea(codeArea);
937+
searchDialog.setSearchStatusListener(searchStatusListener);
878938
searchDialog.setOnCloseListener(() -> {
879-
searchParameters = searchDialog.getSearchParameters();
939+
SearchParameters usedSearchParameters = searchDialog.getSearchParameters();
940+
if (usedSearchParameters != null) {
941+
searchParameters = usedSearchParameters;
942+
}
880943
});
881944
searchDialog.show(getSupportFragmentManager(), "searchDialog");
882945
return true;
@@ -1389,6 +1452,24 @@ public void buttonActionTab(View view) {
13891452
codeArea.getCommandHandler().keyPressed(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_TAB));
13901453
}
13911454

1455+
public void buttonActionPreviousMatch(View view) {
1456+
SearchCodeAreaColorAssessor searchAssessor = CodeAreaAndroidUtils.findColorAssessor((ColorAssessorPainterCapable) codeArea.getPainter(), SearchCodeAreaColorAssessor.class);
1457+
searchAssessor.setCurrentMatchIndex(searchAssessor.getCurrentMatchIndex() - 1);
1458+
updateSearchStatusPanel(searchAssessor.getCurrentMatchIndex(), searchAssessor.getMatches().size());
1459+
}
1460+
1461+
public void buttonActionNextMatch(View view) {
1462+
SearchCodeAreaColorAssessor searchAssessor = CodeAreaAndroidUtils.findColorAssessor((ColorAssessorPainterCapable) codeArea.getPainter(), SearchCodeAreaColorAssessor.class);
1463+
searchAssessor.setCurrentMatchIndex(searchAssessor.getCurrentMatchIndex() + 1);
1464+
updateSearchStatusPanel(searchAssessor.getCurrentMatchIndex(), searchAssessor.getMatches().size());
1465+
}
1466+
1467+
public void buttonActionHideSearchPanel(View view) {
1468+
binarySearch.cancelSearch();
1469+
binarySearch.clearSearch();
1470+
hideSearchStatusPanel();
1471+
}
1472+
13921473
public static boolean isGoogleTV(Context context) {
13931474
final PackageManager pm = context.getPackageManager();
13941475
return pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK);

app/src/main/java/org/exbin/bined/editor/android/search/BinarySearch.java

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@
1515
*/
1616
package org.exbin.bined.editor.android.search;
1717

18-
import java.util.logging.Level;
19-
import java.util.logging.Logger;
20-
2118
import javax.annotation.Nonnull;
2219
import javax.annotation.Nullable;
2320
import javax.annotation.ParametersAreNonnullByDefault;
@@ -39,41 +36,16 @@ public class BinarySearch {
3936
private SearchParameters.SearchDirection currentSearchDirection = SearchParameters.SearchDirection.FORWARD;
4037
private final SearchParameters currentSearchParameters = new SearchParameters();
4138
private final ReplaceParameters currentReplaceParameters = new ReplaceParameters();
42-
private BinarySearchService.FoundMatches foundMatches = new BinarySearchService.FoundMatches();
4339

4440
// private final List<SearchCondition> searchHistory = new ArrayList<>();
4541
// private final List<SearchCondition> replaceHistory = new ArrayList<>();
4642

4743
// private CodeAreaPopupMenuHandler codeAreaPopupMenuHandler;
4844
private PanelClosingListener panelClosingListener = null;
4945
private BinarySearchService binarySearchService;
50-
private final BinarySearchService.SearchStatusListener searchStatusListener;
46+
private BinarySearchService.SearchStatusListener searchStatusListener;
5147

5248
public BinarySearch() {
53-
searchStatusListener = new BinarySearchService.SearchStatusListener() {
54-
55-
@Override
56-
public void setStatus(BinarySearchService.FoundMatches foundMatches, SearchParameters.MatchMode matchMode) {
57-
BinarySearch.this.foundMatches = foundMatches;
58-
updateMatchStatus();
59-
}
60-
61-
@Override
62-
public void clearStatus() {
63-
BinarySearch.this.foundMatches = new BinarySearchService.FoundMatches();
64-
updateMatchStatus();
65-
}
66-
67-
private void updateMatchStatus() {
68-
int matchesCount = foundMatches.getMatchesCount();
69-
int matchPosition = foundMatches.getMatchPosition();
70-
// TODO Search panel
71-
// binarySearchPanel.updateMatchStatus(matchesCount > 0,
72-
// matchesCount > 1 && matchPosition > 0,
73-
// matchPosition < matchesCount - 1
74-
// );
75-
}
76-
};
7749
}
7850

7951
public void setBinarySearchService(BinarySearchService binarySearchService) {
@@ -122,11 +94,13 @@ private void invokeSearch(SearchOperation searchOperation, SearchParameters sear
12294

12395
// TODO Move to search panel
12496
public void performFind(SearchParameters searchParameters, BinarySearchService.SearchStatusListener searchStatusListener) {
97+
this.searchStatusListener = searchStatusListener;
12598
invokeSearch(SearchOperation.FIND, searchParameters, null, 0);
12699
}
127100

128101
// TODO Move to search panel
129102
public void performFindAgain(BinarySearchService.SearchStatusListener searchStatusListener) {
103+
this.searchStatusListener = searchStatusListener;
130104
invokeSearch(SearchOperation.FIND_AGAIN, currentSearchParameters, currentReplaceParameters, 0);
131105
}
132106

@@ -143,7 +117,9 @@ public void clearSearch() {
143117
SearchCondition condition = currentSearchParameters.getCondition();
144118
condition.clear();
145119
binarySearchService.clearMatches();
146-
searchStatusListener.clearStatus();
120+
if (searchStatusListener != null) {
121+
searchStatusListener.clearStatus();
122+
}
147123
}
148124

149125
public void dataChanged() {

app/src/main/java/org/exbin/bined/editor/android/search/SearchDialog.java

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import android.view.KeyEvent;
2727
import android.view.LayoutInflater;
2828
import android.view.View;
29+
import android.view.WindowManager;
2930
import android.view.inputmethod.InputMethodManager;
3031
import android.widget.EditText;
3132
import android.widget.FrameLayout;
@@ -65,17 +66,7 @@ public class SearchDialog extends AppCompatDialogFragment {
6566
private SearchParameters searchParameters = null;
6667

6768
private BinarySearch binarySearch;
68-
private final BinarySearchService.SearchStatusListener searchStatusListener = new BinarySearchService.SearchStatusListener() {
69-
@Override
70-
public void setStatus(BinarySearchService.FoundMatches foundMatches, SearchParameters.MatchMode matchMode) {
71-
// TODO Add search status panel
72-
}
73-
74-
@Override
75-
public void clearStatus() {
76-
77-
}
78-
};
69+
private BinarySearchService.SearchStatusListener searchStatusListener;
7970
private final CodeAreaCaretListener codeAreaCodeAreaCaretListener = caretPosition -> {
8071
boolean showKeyboard = true;
8172
if (showKeyboard != keyboardShown) {
@@ -86,10 +77,13 @@ public void clearStatus() {
8677
if (showKeyboard) {
8778
// TODO im.setInputMethodAndSubtype();
8879
im.showSoftInput(codeArea, InputMethodManager.SHOW_IMPLICIT);
89-
// TODO refit dialog
9080
} else {
9181
im.hideSoftInputFromWindow(codeArea.getWindowToken(), 0);
9282
}
83+
Dialog dialog = SearchDialog.this.getDialog();
84+
if (dialog != null) {
85+
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
86+
}
9387
}
9488
};
9589
private CloseListener closeListener = null;
@@ -111,6 +105,10 @@ public void setSearchParameters(@Nullable SearchParameters searchParameters) {
111105
this.searchParameters = searchParameters;
112106
}
113107

108+
public void setSearchStatusListener(BinarySearchService.SearchStatusListener searchStatusListener) {
109+
this.searchStatusListener = searchStatusListener;
110+
}
111+
114112
@Nonnull
115113
@Override
116114
public Dialog onCreateDialog(Bundle savedInstanceState) {
@@ -120,8 +118,8 @@ public Dialog onCreateDialog(Bundle savedInstanceState) {
120118
codeArea.setEditOperation(EditOperation.INSERT);
121119
codeArea.addCaretMovedListener(codeAreaCodeAreaCaretListener);
122120
codeArea.setOnKeyListener(new CodeAreaKeyListener());
123-
codeArea.setOnFocusChangeListener((v, hasFocus) -> {
124-
if (v == codeArea) {
121+
codeArea.setOnFocusChangeListener((view, hasFocus) -> {
122+
if (view == codeArea) {
125123
if (hasFocus) {
126124
codeAreaCodeAreaCaretListener.caretMoved(codeArea.getActiveCaretPosition());
127125
} else {
@@ -142,6 +140,10 @@ public Dialog onCreateDialog(Bundle savedInstanceState) {
142140

143141
LayoutInflater inflater = activity.getLayoutInflater();
144142
searchView = inflater.inflate(R.layout.search_view, null);
143+
TabLayout tabLayout = searchView.findViewById(R.id.tabLayout);
144+
145+
FrameLayout frameLayout = searchView.findViewById(R.id.frameLayout);
146+
frameLayout.addView(editText);
145147

146148
if (searchParameters != null) {
147149
SearchCondition condition = searchParameters.getCondition();
@@ -154,6 +156,9 @@ public Dialog onCreateDialog(Bundle savedInstanceState) {
154156
data.clear();
155157
data.insert(0, condition.getBinaryData());
156158
codeAreaCodeAreaCaretListener.caretMoved(codeArea.getActiveCaretPosition());
159+
TabLayout.Tab binaryTab = tabLayout.getTabAt(1);
160+
tabLayout.selectTab(binaryTab);
161+
tabSwitched(binaryTab);
157162
}
158163
SwitchCompat matchCaseSwitch = searchView.findViewById(R.id.match_case);
159164
matchCaseSwitch.setChecked(searchParameters.isMatchCase());
@@ -165,20 +170,10 @@ public Dialog onCreateDialog(Bundle savedInstanceState) {
165170
fromCursorSwitch.setChecked(searchParameters.isSearchFromCursor());
166171
}
167172

168-
FrameLayout frameLayout = searchView.findViewById(R.id.frameLayout);
169-
frameLayout.addView(editText);
170-
TabLayout tabLayout = searchView.findViewById(R.id.tabLayout);
171173
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
172174
@Override
173175
public void onTabSelected(TabLayout.Tab tab) {
174-
int tabPos = tab.getPosition();
175-
if (tabPos != lastTab) {
176-
frameLayout.removeView(lastTab == 0 ? editText : codeArea);
177-
frameLayout.addView(tabPos == 0 ? editText : codeArea);
178-
SwitchCompat matchCaseSwitch = searchView.findViewById(R.id.match_case);
179-
matchCaseSwitch.setEnabled(tabPos == 0);
180-
lastTab = tabPos;
181-
}
176+
tabSwitched(tab);
182177
}
183178

184179
@Override
@@ -228,6 +223,18 @@ public void onTabReselected(TabLayout.Tab tab) {
228223
return builder.create();
229224
}
230225

226+
private void tabSwitched(TabLayout.Tab tab) {
227+
FrameLayout frameLayout = searchView.findViewById(R.id.frameLayout);
228+
int tabPos = tab.getPosition();
229+
if (tabPos != lastTab) {
230+
frameLayout.removeView(lastTab == 0 ? editText : codeArea);
231+
frameLayout.addView(tabPos == 0 ? editText : codeArea);
232+
SwitchCompat matchCaseSwitch = searchView.findViewById(R.id.match_case);
233+
matchCaseSwitch.setEnabled(tabPos == 0);
234+
lastTab = tabPos;
235+
}
236+
}
237+
231238
public void setOnCloseListener(CloseListener closeListener) {
232239
this.closeListener = closeListener;
233240
}

app/src/main/res/layout/about_view.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
android:paddingLeft="10dp"
4444
android:paddingTop="10dp"
4545
android:paddingRight="10dp"
46-
android:text="Miroslav Hajda\nReza Almanda (app logo)\nGovind S Nair (Hindi translation)\nWeiguangTWK (Chinese translation)\nThomas Reis (Portuguese translation)\nbaturax (Turkish translation)"
46+
android:text="Miroslav Hajda\nReza Almanda (app logo)\nGovind S Nair (Hindi translation)\nWeiguangTWK (Chinese translation)\nThomas Reis (Portuguese translation)\nBaturax (Turkish translation)"
4747
tools:ignore="HardcodedText" />
4848
</LinearLayout>
4949
</ScrollView>

0 commit comments

Comments
 (0)