Skip to content

Commit

Permalink
Basic search capability
Browse files Browse the repository at this point in the history
  • Loading branch information
hajdam committed Sep 26, 2024
1 parent d46bed3 commit a9e146a
Show file tree
Hide file tree
Showing 7 changed files with 817 additions and 15 deletions.
70 changes: 56 additions & 14 deletions app/src/main/java/org/exbin/bined/editor/android/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.core.os.LocaleListCompat;

Expand All @@ -66,6 +67,10 @@
import org.exbin.bined.editor.android.preference.FontPreference;
import org.exbin.bined.editor.android.preference.MainPreferences;
import org.exbin.bined.editor.android.preference.PreferencesWrapper;
import org.exbin.bined.editor.android.search.BinarySearchService;
import org.exbin.bined.editor.android.search.BinarySearchServiceImpl;
import org.exbin.bined.editor.android.search.SearchCondition;
import org.exbin.bined.editor.android.search.SearchParameters;
import org.exbin.bined.highlight.android.HighlightNonAsciiCodeAreaPainter;
import org.exbin.bined.operation.android.CodeAreaOperationCommandHandler;
import org.exbin.bined.operation.android.CodeAreaUndoRedo;
Expand Down Expand Up @@ -115,6 +120,18 @@ public class MainActivity extends AppCompatActivity {
private static ByteArrayEditableData fileData = null;
private Uri currentFileUri = null;
private final BinaryStatusHandler binaryStatus = new BinaryStatusHandler(this);
private BinarySearchService searchService;
private final BinarySearchService.SearchStatusListener searchStatusListener = new BinarySearchService.SearchStatusListener() {
@Override
public void setStatus(BinarySearchService.FoundMatches foundMatches, SearchParameters.MatchMode matchMode) {
// TODO Add search status panel
}

@Override
public void clearStatus() {

}
};

private boolean keyboardShown = false;
private BinaryEditorPreferences appPreferences;
Expand Down Expand Up @@ -142,18 +159,9 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

// FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
// fab.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
// .setAction("Action", null).show();
// }
// });

codeArea = findViewById(R.id.codeArea);
codeArea.setEditOperation(EditOperation.INSERT);

searchService = new BinarySearchServiceImpl(codeArea);

undoRedo = new CodeAreaUndoRedo(codeArea);
undoRedo.addChangeListener(() -> {
Expand Down Expand Up @@ -248,9 +256,7 @@ private void processKeys(KeyEvent keyEvent) {
}
});

codeArea.addEditModeChangedListener((EditMode mode, EditOperation operation) -> {
binaryStatus.setEditMode(mode, operation);
});
codeArea.addEditModeChangedListener(binaryStatus::setEditMode);

applySettings();
}
Expand Down Expand Up @@ -310,6 +316,9 @@ public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
updateUndoState();

codeArea.addSelectionChangedListener(this::updateEditActionsState);
updateEditActionsState();

menu.findItem(R.id.code_colorization).setChecked(appPreferences.getCodeAreaPreferences().isCodeColorization());
int bytesPerRow = appPreferences.getCodeAreaPreferences().getMaxBytesPerRow();
switch (bytesPerRow) {
Expand All @@ -335,6 +344,27 @@ public boolean onCreateOptionsMenu(Menu menu) {
}
}

MenuItem searchMenuItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchMenuItem.getActionView();
searchView.setSubmitButtonEnabled(true);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
searchService.performFindAgain(searchStatusListener);
return true;
}

@Override
public boolean onQueryTextChange(String newText) {
SearchCondition searchCondition = new SearchCondition();
searchCondition.setSearchText(newText);
SearchParameters searchParameters = new SearchParameters();
searchParameters.setCondition(searchCondition);
searchService.performFind(searchParameters, searchStatusListener);
return true;
}
});

return true;
}

Expand Down Expand Up @@ -631,7 +661,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
}

public void releaseFile(PostReleaseAction postReleaseAction) {
if (!undoRedo.isModified() || currentFileUri == null) {
if (!undoRedo.isModified()) {
postReleaseAction.released(true);
return;
}
Expand Down Expand Up @@ -804,6 +834,18 @@ private void updateCurrentEditMode() {
binaryStatus.setEditMode(codeArea.getEditMode(), codeArea.getActiveOperation());
}

private void updateEditActionsState() {
MenuItem cutMenuItem = menu.findItem(R.id.action_cut);
cutMenuItem.setEnabled(codeArea.isEditable() && codeArea.hasSelection());

MenuItem copyMenuItem = menu.findItem(R.id.action_copy);
copyMenuItem.setEnabled(codeArea.hasSelection());
MenuItem pasteMenuItem = menu.findItem(R.id.action_paste);
pasteMenuItem.setEnabled(codeArea.isEditable() && codeArea.canPaste());
MenuItem deleteMenuItem = menu.findItem(R.id.action_delete);
deleteMenuItem.setEnabled(codeArea.isEditable() && codeArea.hasSelection());
}

private void updateUndoState() {
MenuItem saveMenuItem = menu.findItem(R.id.action_save);
saveMenuItem.setEnabled(currentFileUri == null || undoRedo.isModified());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright (C) ExBin Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.exbin.bined.editor.android.search;

import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;

/**
* Binary search service.
*
* @author ExBin Project (https://exbin.org)
*/
@ParametersAreNonnullByDefault
public interface BinarySearchService {

void performFind(SearchParameters dialogSearchParameters, SearchStatusListener searchStatusListener);

void setMatchPosition(int matchPosition);

void performFindAgain(SearchStatusListener searchStatusListener);

void performReplace(SearchParameters searchParameters, ReplaceParameters replaceParameters);

@Nonnull
SearchParameters getLastSearchParameters();

void clearMatches();

@ParametersAreNonnullByDefault
public interface SearchStatusListener {

void setStatus(FoundMatches foundMatches, SearchParameters.MatchMode matchMode);

void clearStatus();
}

public static class FoundMatches {

private int matchesCount;
private int matchPosition;

public FoundMatches() {
matchesCount = 0;
matchPosition = -1;
}

public FoundMatches(int matchesCount, int matchPosition) {
if (matchPosition >= matchesCount) {
throw new IllegalStateException("Match position is out of range");
}

this.matchesCount = matchesCount;
this.matchPosition = matchPosition;
}

public int getMatchesCount() {
return matchesCount;
}

public int getMatchPosition() {
return matchPosition;
}

public void setMatchesCount(int matchesCount) {
this.matchesCount = matchesCount;
}

public void setMatchPosition(int matchPosition) {
this.matchPosition = matchPosition;
}

public void next() {
if (matchPosition == matchesCount - 1) {
throw new IllegalStateException("Cannot find next on last match");
}

matchPosition++;
}

public void prev() {
if (matchPosition == 0) {
throw new IllegalStateException("Cannot find previous on first match");
}

matchPosition--;
}
}
}
Loading

0 comments on commit a9e146a

Please sign in to comment.