diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index aa26825..2db19ba 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,6 +6,7 @@
+
-
+
+
+
+
+
diff --git a/app/src/main/java/com/maxistar/textpad/activities/EditorActivity.java b/app/src/main/java/com/maxistar/textpad/activities/EditorActivity.java
index 94591af..e82f927 100644
--- a/app/src/main/java/com/maxistar/textpad/activities/EditorActivity.java
+++ b/app/src/main/java/com/maxistar/textpad/activities/EditorActivity.java
@@ -39,10 +39,12 @@
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.EditText;
+import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.SearchView;
import android.widget.Toast;
@@ -53,6 +55,7 @@
import com.maxistar.textpad.ServiceLocator;
import com.maxistar.textpad.service.SettingsService;
import com.maxistar.textpad.TPStrings;
+import com.maxistar.textpad.tts.Dictator;
import com.maxistar.textpad.service.AlternativeUrlsService;
import com.maxistar.textpad.service.RecentFilesService;
import com.maxistar.textpad.service.ThemeService;
@@ -106,7 +109,7 @@ public class EditorActivity extends AppCompatActivity {
Uri lastTriedSystemUri = null;
-
+
boolean changed = false;
boolean exitDialogShown = false;
@@ -309,7 +312,7 @@ public void onSaveInstanceState(@NonNull Bundle outState) {
protected void onStop() {
super.onStop();
}
-
+
@Override
public void onBackPressed() {
if (this.changed && !exitDialogShown) {
@@ -475,7 +478,7 @@ public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem redoMenu = menu.findItem(R.id.menu_edit_redo);
redoMenu.setEnabled(editTextUndoRedo.getCanRedo());
-
+
updateRecentFiles(menu);
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
@@ -608,6 +611,8 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
openRecentFile(4);
} else if (itemId == R.id.menu_document_new) {
newFile();
+ } else if (itemId == R.id.menu_dictate) {
+ startDictation();
} else if (itemId == R.id.menu_document_save) {
saveFile();
} else if (itemId == R.id.menu_document_save_as) {
@@ -709,6 +714,13 @@ private void showSettings() {
}
}
+ private void startDictation() {
+ ProgressBar view = findViewById(R.id.speechProgressBar);
+ view.setVisibility(View.VISIBLE);
+ Dictator dictator = new Dictator();
+ dictator.startDictation(mText, this, view);
+ }
+
private void showSettingsActivity() {
Intent intent = new Intent(this.getBaseContext(),
SettingsActivity.class);
@@ -859,7 +871,7 @@ protected void exitApplication() {
System.exitFromApp(EditorActivity.this);
}
}
-
+
protected void selectFileUsingAndroidSystemPicker() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
diff --git a/app/src/main/java/com/maxistar/textpad/nlp/tokenizer/GenericTokenizer.java b/app/src/main/java/com/maxistar/textpad/nlp/tokenizer/GenericTokenizer.java
new file mode 100644
index 0000000..2484411
--- /dev/null
+++ b/app/src/main/java/com/maxistar/textpad/nlp/tokenizer/GenericTokenizer.java
@@ -0,0 +1,80 @@
+package com.maxistar.textpad.nlp.tokenizer;
+
+import java.util.ArrayList;
+
+public class GenericTokenizer {
+ final static int MODE_DEFAULT = 0;
+ final static int MODE_PUNCTUATION = 1;
+ final static int MODE_WHITESPACE = 2;
+ final static int MODE_WORD = 3;
+
+ public String[] tokenizeString(String input) {
+ int length = input.length();
+ int mode = MODE_DEFAULT;
+ ArrayList result = new ArrayList<>();
+ StringBuilder currentWord = new StringBuilder();
+ for (int i = 0; i < length; i++) {
+ String currentChar = input.substring(i, i + 1);
+ if (mode == MODE_WORD) {
+ if (isLetter(currentChar)) {
+ currentWord.append(currentChar);
+ } else if (isPunctuation(currentChar)) {
+ result.add(currentWord.toString());
+ result.add(currentChar);
+ mode = MODE_PUNCTUATION;
+ currentWord = new StringBuilder();
+ } else if (isWhitespace(currentChar)) {
+ result.add(currentWord.toString());
+ result.add(currentChar);
+ mode = MODE_WHITESPACE;
+ currentWord = new StringBuilder();
+ }
+ } else if (mode == MODE_PUNCTUATION) {
+ if (isLetter(currentChar)) {
+ currentWord.append(currentChar);
+ mode = MODE_WORD;
+ } else if (isPunctuation(currentChar)) {
+ result.add(currentChar);
+ } else if (isWhitespace(currentChar)) {
+ result.add(currentChar);
+ mode = MODE_WHITESPACE;
+ }
+ } else if (mode == MODE_WHITESPACE) {
+ if (isLetter(currentChar)) {
+ currentWord.append(currentChar);
+ mode = MODE_WORD;
+ } else if (isPunctuation(currentChar)) {
+ result.add(currentChar);
+ mode = MODE_PUNCTUATION;
+ } else if (isWhitespace(currentChar)) {
+ result.add(currentChar);
+ }
+ } else {
+ if (isLetter(currentChar)) {
+ currentWord.append(currentChar);
+ mode = MODE_WORD;
+ } else if (isPunctuation(currentChar)) {
+ result.add(currentChar);
+ mode = MODE_PUNCTUATION;
+ } else if (isWhitespace(currentChar)) {
+ result.add(currentChar);
+ mode = MODE_WHITESPACE;
+ }
+ }
+ }
+ String[] res = new String[result.size()];
+ return result.toArray(res);
+ }
+
+ private boolean isWhitespace(String currentChar) {
+ return currentChar.equals(" ") || currentChar.equals("\n");
+ }
+
+ private boolean isPunctuation(String currentChar) {
+ return currentChar.matches("[—?,:;.…!«»)(]");
+ }
+
+ private boolean isLetter(String currentChar) {
+ return currentChar.matches("[a-zA-Zа-яА-Я\\-]");
+ }
+}
diff --git a/app/src/main/java/com/maxistar/textpad/tts/Dictator.java b/app/src/main/java/com/maxistar/textpad/tts/Dictator.java
new file mode 100644
index 0000000..bdec3b5
--- /dev/null
+++ b/app/src/main/java/com/maxistar/textpad/tts/Dictator.java
@@ -0,0 +1,386 @@
+package com.maxistar.textpad.tts;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.Color;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.speech.RecognitionListener;
+import android.speech.RecognizerIntent;
+import android.speech.SpeechRecognizer;
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.UtteranceProgressListener;
+import android.text.Editable;
+import android.text.Spanned;
+import android.text.style.BackgroundColorSpan;
+import android.util.Log;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.ProgressBar;
+import android.widget.Toast;
+
+import com.maxistar.textpad.R;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+public class Dictator implements RecognitionListener {
+
+ private final String LOG_TAG = "VoiceRecognition";
+
+ private ProgressBar speechProgressBar;
+
+ private SpeechRecognizer speech = null;
+
+ private EditText mText;
+
+ VoiceReader voiceReader;
+
+ public Dictator() {
+ voiceReader = new VoiceReader();
+ }
+
+ Context context;
+
+ String lastDictation = "";
+
+ static final int COMMAND_MODE = 0;
+ static final int DICTATION_MODE = 1;
+
+ static final int COMMAND_NONE = 0;
+ static final int COMMAND_UNKNOWN = 1;
+ static final int COMMAND_DICTATE = 2;
+ static final int COMMAND_EXIT = 3;
+ static final int COMMAND_REPEAT = 4;
+ static final int COMMAND_SELECT_SENTENCE = 5;
+
+ int mode = 0;
+ int lastCommand = 0;
+
+ public void startDictation(EditText mText, Activity context, ProgressBar speechProgressBar) {
+
+ this.context = context;
+
+
+ this.speechProgressBar = speechProgressBar;
+ this.mText = mText;
+ checkPermissions(context);
+
+ speech = SpeechRecognizer.createSpeechRecognizer(context);
+ speech.setRecognitionListener(this);
+ //startHearing(context);
+
+ sayWaitingForCommand();
+ }
+
+ public void sayWaitingForCommand() {
+ sayMessage(R.string.tts_waiting_the_command);
+ }
+
+
+ public void sayReady() {
+ sayMessage(R.string.tts_ready_to_dictate);
+ }
+
+ public void sayMessage(int stringId) {
+ sayString(context.getResources().getString(stringId));
+ }
+
+ public void sayString(String str) {
+ Locale locale = Locale.getDefault();
+ String timeStr = String.valueOf(System.currentTimeMillis());
+ voiceReader.speak(str, "somerandomkey" + timeStr, locale);
+ }
+
+ public void startHearing(Context context) {
+ Intent recognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
+ String language = "ru";
+ recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, language);
+ recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language);
+ recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
+ recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, context.getPackageName());
+ recognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 10);
+ speech.startListening(recognizerIntent);
+ }
+
+ private void checkPermissions(Activity context) {
+ if (ContextCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
+ return;
+ }
+
+ if (ActivityCompat.shouldShowRequestPermissionRationale(context, Manifest.permission.RECORD_AUDIO)) {
+ Toast.makeText(context, "", Toast.LENGTH_SHORT).show();
+ } else {
+ ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.RECORD_AUDIO}, 1);
+ }
+ }
+
+ @Override
+ public void onReadyForSpeech(Bundle bundle) {
+ Log.i(LOG_TAG, "onReadyForSpeech");
+ }
+
+ @Override
+ public void onBeginningOfSpeech() {
+ speechProgressBar.setVisibility(View.VISIBLE);
+ Log.i(LOG_TAG, "onBeginningOfSpeech");
+ speechProgressBar.setIndeterminate(false);
+ speechProgressBar.setMax(10);
+ }
+
+ @Override
+ public void onRmsChanged(float rmsdB) {
+ Log.i(LOG_TAG, "onRmsChanged: " + rmsdB);
+ speechProgressBar.setProgress((int) rmsdB);
+ }
+
+ @Override
+ public void onBufferReceived(byte[] bytes) {
+ Log.i(LOG_TAG, "onBufferReceived: " + bytes);
+ }
+
+ @Override
+ public void onEndOfSpeech() {
+ Log.i(LOG_TAG, "onEndOfSpeech");
+ speechProgressBar.setIndeterminate(true);
+ //toggleButton.setChecked(false);
+ }
+
+ @Override
+ public void onError(int errorCode) {
+ speechProgressBar.setVisibility(View.INVISIBLE);
+ String errorMessage = getErrorText(errorCode);
+ Log.d(LOG_TAG, "FAILED " + errorMessage);
+ }
+
+ @Override
+ public void onResults(Bundle results) {
+ speechProgressBar.setVisibility(View.INVISIBLE);
+ Log.i("LOG", "onResults");
+ ArrayList result = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
+
+ if (mode == COMMAND_MODE) {
+ if (isCommandDictate(result)) {
+ lastCommand = COMMAND_DICTATE;
+ sayReady();
+ } else if (isCommandSelectSentence(result)) {
+ lastCommand = COMMAND_SELECT_SENTENCE;
+ selectSentence();
+ } else if (isCommandRepeat(result)) {
+ lastCommand = COMMAND_REPEAT;
+ repeatLast();
+ } else if (isCommandExit(result)) {
+ lastCommand = COMMAND_EXIT;
+ sayGoodBye();
+ } else {
+ lastCommand = COMMAND_UNKNOWN;
+ sayUnknownCommand();
+ }
+ } else { //dictation
+ lastDictation = result.get(0);
+ this.mText.setText(result.get(0) + "\n" + this.mText.getText());
+ mode = COMMAND_MODE;
+ lastCommand = COMMAND_NONE;
+ sayWaitingForCommand();
+ }
+ }
+
+ void sayGoodBye() {
+ sayMessage(R.string.tts_good_bye);
+ }
+
+ void sayUnknownCommand() {
+ sayMessage(R.string.tts_unknown_command);
+ }
+
+ void selectSentence() {
+ sayMessage(R.string.tts_sentence_selected);
+
+ Editable editable = mText.getEditableText();
+ final BackgroundColorSpan span = new BackgroundColorSpan(Color.YELLOW);
+ editable.setSpan(
+ span,
+ 0,
+ 10,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+ );
+ }
+
+ void repeatLast() {
+ sayString(lastDictation);
+ }
+
+ boolean isCommandSelectSentence(ArrayList result) {
+ String command = context.getResources().getString(R.string.tts_select_sentence);
+ for (String variant : result) {
+ if (command.toLowerCase().equals(variant.toLowerCase())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean isCommandRepeat(ArrayList result) {
+ String command = context.getResources().getString(R.string.tts_repeat);
+ for (String variant : result) {
+ if (command.toLowerCase().equals(variant.toLowerCase())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean isCommandDictate(ArrayList result) {
+ String command = context.getResources().getString(R.string.tts_dictate);
+ for (String variant : result) {
+ if (command.toLowerCase().equals(variant.toLowerCase())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean isCommandExit(ArrayList result) {
+ String command = context.getResources().getString(R.string.tts_done);
+ for (String variant : result) {
+ if (command.toLowerCase().equals(variant.toLowerCase())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void onPartialResults(Bundle bundle) {
+ Log.i(LOG_TAG, "onPartialResults");
+ }
+
+ @Override
+ public void onEvent(int i, Bundle bundle) {
+ Log.i(LOG_TAG, "onEvent");
+ }
+
+ public static String getErrorText(int errorCode) {
+ String message;
+ switch (errorCode) {
+ case SpeechRecognizer.ERROR_AUDIO:
+ message = "Audio recording error";
+ break;
+ case SpeechRecognizer.ERROR_CLIENT:
+ message = "Client side error";
+ break;
+ case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
+ message = "Insufficient permissions";
+ break;
+ case SpeechRecognizer.ERROR_NETWORK:
+ message = "Network error";
+ break;
+ case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
+ message = "Network timeout";
+ break;
+ case SpeechRecognizer.ERROR_NO_MATCH:
+ message = "No match";
+ break;
+ case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
+ message = "RecognitionService busy";
+ break;
+ case SpeechRecognizer.ERROR_SERVER:
+ message = "error from server";
+ break;
+ case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
+ message = "No speech input";
+ break;
+ default:
+ message = "Didn't understand, please try again.";
+ break;
+ }
+ return message;
+ }
+
+ class VoiceReader {
+ TextToSpeech tts;
+ boolean ttsReady = false;
+ boolean speaking = false;
+ String text;
+ String textId;
+ Locale locale;
+
+ void init(Context context) {
+ tts = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
+ @Override
+ public void onInit(int status) {
+ // set our locale only if init was success.
+ if (status == TextToSpeech.SUCCESS) {
+ ttsReady = true;
+ speak(text, "word:" + textId, locale);
+ }
+ }
+ });
+ tts.setLanguage(locale);
+ tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
+ @Override
+ public void onStart(String s) {
+ speaking = true;
+ }
+
+ @Override
+ public void onDone(String s) {
+ speaking = false;
+ if (mode == COMMAND_MODE) {
+ if (lastCommand == COMMAND_DICTATE) {
+ mode = DICTATION_MODE;
+ startHearingDelay();
+ } else if (lastCommand == COMMAND_SELECT_SENTENCE) {
+
+
+ } else if (lastCommand == COMMAND_EXIT) {
+ //exit
+ } else if (lastCommand == COMMAND_REPEAT) {
+ lastCommand = COMMAND_NONE;
+ sayWaitingForCommand();
+ } else if (lastCommand == COMMAND_UNKNOWN) {
+ startHearingDelay();
+ } else {
+ startHearingDelay();
+ }
+ }
+ }
+
+ @Override
+ public void onError(String s) {
+ speaking = false;
+ }
+ });
+ }
+
+ void startHearingDelay() {
+ final Handler handler = new Handler(Looper.getMainLooper());
+ handler.postDelayed(() -> startHearing(context), 100);
+ }
+
+ private void speak(String phrase, String id, Locale locale) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
+ this.text = phrase;
+ this.textId = id;
+ this.locale = locale;
+ if (tts == null) {
+ this.init(context);
+ return;
+ }
+ if (!ttsReady) {
+ return;
+ }
+
+ tts.setLanguage(locale);
+ tts.speak(phrase, TextToSpeech.QUEUE_ADD, null, id);
+ }
+ }
+}
diff --git a/app/src/main/java/com/maxistar/textpad/tts/TextSplitter.java b/app/src/main/java/com/maxistar/textpad/tts/TextSplitter.java
new file mode 100644
index 0000000..b69f0cc
--- /dev/null
+++ b/app/src/main/java/com/maxistar/textpad/tts/TextSplitter.java
@@ -0,0 +1,20 @@
+package com.maxistar.textpad.tts;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.text.BreakIterator;
+import java.util.Locale;
+
+public class TextSplitter {
+ void test() {
+ BreakIterator iterator = BreakIterator.getSentenceInstance(Locale.US);
+ String source = "This is a test. This is a T.L.A. test. Now with a Dr. in it.";
+ iterator.setText(source);
+ int start = iterator.first();
+ for (int end = iterator.next();
+ end != BreakIterator.DONE;
+ start = end, end = iterator.next()) {
+ System.out.println(source.substring(start,end));
+ }
+ }
+}
diff --git a/app/src/main/res/drawable-anydpi/ic_dictate.xml b/app/src/main/res/drawable-anydpi/ic_dictate.xml
new file mode 100644
index 0000000..616070b
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_dictate.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/app/src/main/res/drawable-anydpi/ic_settings.xml b/app/src/main/res/drawable-anydpi/ic_settings.xml
index 3c4f8c8..5350109 100644
--- a/app/src/main/res/drawable-anydpi/ic_settings.xml
+++ b/app/src/main/res/drawable-anydpi/ic_settings.xml
@@ -1,5 +1,4 @@
-
+
+
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/main_menu.xml b/app/src/main/res/menu/main_menu.xml
index 6644248..43989ed 100644
--- a/app/src/main/res/menu/main_menu.xml
+++ b/app/src/main/res/menu/main_menu.xml
@@ -95,6 +95,11 @@
android:title="@string/Menu_Print"
android:icon="@drawable/ic_print"
app:iconTint="@color/colorIcon" />
+
- مخصص
+ Dictate
+
+ waiting the command
+ ready to dictate
+ dictate
+ done
+ read last sentence
+ go to start
+ go to end
+ do not understand
+ read current sentence
+ proceed
+ further
+ good bye
+ unknown command
+ repeat
+ select sentence
+ sentence selected
\ No newline at end of file
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 8a0bca6..d9a16b5 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -100,4 +100,22 @@
Brauch
+ Dictate
+
+ waiting the command
+ ready to dictate
+ dictate
+ done
+ read last sentence
+ go to start
+ go to end
+ do not understand
+ read current sentence
+ proceed
+ further
+ good bye
+ unknown command
+ repeat
+ select sentence
+ sentence selected
\ No newline at end of file
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 4666f3d..0e49f15 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -100,4 +100,22 @@
Costumbre
+ Dictate
+
+ waiting the command
+ ready to dictate
+ dictate
+ done
+ read last sentence
+ go to start
+ go to end
+ do not understand
+ read current sentence
+ proceed
+ further
+ good bye
+ unknown command
+ repeat
+ select sentence
+ sentence selected
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 666f50f..819b4a7 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -100,4 +100,22 @@
Costume
+ Dictate
+
+ waiting the command
+ ready to dictate
+ dictate
+ done
+ read last sentence
+ go to start
+ go to end
+ do not understand
+ read current sentence
+ proceed
+ further
+ good bye
+ unknown command
+ repeat
+ select sentence
+ sentence selected
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index fe00580..56bf629 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -100,4 +100,22 @@
Personalizada
+ Dictate
+
+ waiting the command
+ ready to dictate
+ dictate
+ done
+ read last sentence
+ go to start
+ go to end
+ do not understand
+ read current sentence
+ proceed
+ further
+ good bye
+ unknown command
+ repeat
+ select sentence
+ sentence selected
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 0e8a30d..fb56294 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -100,4 +100,22 @@
Пользовательская
+ Dictate
+
+ ожидаю команду
+ готов к диктовке
+ диктовать
+ готово
+ прочитать последнее предложение
+ перейти в начало
+ перейти в конец
+ не понимаю
+ прочитать текущее предложение
+ продолжай
+ дальше
+ пока
+ неизвестная команда
+ повтори
+ выделите предложение
+ предложение выделено
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 21f5de3..793b1a7 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -101,4 +101,22 @@
Gelenek
+ Dictate
+
+ waiting the command
+ ready to dictate
+ dictate
+ done
+ read last sentence
+ go to start
+ go to end
+ do not understand
+ read current sentence
+ proceed
+ further
+ good bye
+ unknown command
+ repeat
+ select sentence
+ sentence selected
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7edab87..7e290b3 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -104,4 +104,22 @@
Custom
+ Dictate
+
+ waiting the command
+ ready to dictate
+ dictate
+ done
+ read last sentence
+ go to start
+ go to end
+ do not understand
+ read current sentence
+ proceed
+ further
+ good bye
+ unknown command
+ repeat
+ select sentence
+ sentence selected
diff --git a/app/src/test/java/com/maxistar/textpad/test/nlp/tokenizer/GenericTokenizerTest.java b/app/src/test/java/com/maxistar/textpad/test/nlp/tokenizer/GenericTokenizerTest.java
new file mode 100644
index 0000000..47cc851
--- /dev/null
+++ b/app/src/test/java/com/maxistar/textpad/test/nlp/tokenizer/GenericTokenizerTest.java
@@ -0,0 +1,67 @@
+package com.maxistar.textpad.test.nlp.tokenizer;
+
+import com.maxistar.textpad.nlp.tokenizer.GenericTokenizer;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+
+public class GenericTokenizerTest {
+
+ @Test
+ public void testTokenizer() {
+ String inputString = "Однажды, в студеную зимнюю пору\n" +
+ "Я из лесу вышел; был сильный мороз.\n" +
+ "Гляжу, поднимается медленно в гору\n" +
+ "Лошадка, везущая хворосту воз.\n" +
+ "И шествуя важно, в спокойствии чинном,\n" +
+ "Лошадку ведет под уздцы мужичок\n" +
+ "В больших сапогах, в полушубке овчинном,\n" +
+ "В больших рукавицах… а сам с ноготок!\n" +
+ "«Здорово парнище!» — «Ступай себе мимо!»\n" +
+ "— «Уж больно ты грозен, как я погляжу!\n" +
+ "Откуда дровишки?» — «Из лесу, вестимо;\n" +
+ "Отец, слышишь, рубит, а я отвожу».\n" +
+ "(В лесу раздавался топор дровосека.)\n" +
+ "«А что, у отца-то большая семья?»\n" +
+ "— «Семья-то большая, да два человека\n" +
+ "Всего мужиков-то: отец мой да я…»\n" +
+ "— «Так вот оно что! А как звать тебя?» — «Власом».\n" +
+ "— «А кой-тебе годик?» — «Шестой миновал…\n" +
+ "Ну, мертвая!» — крикнул малюточка басом,\n" +
+ "Рванул под уздцы и быстрей зашагал.";
+
+ String PUNCTUATION_SPACE = " ";
+ String PUNCTUATION_COMA = ",";
+ String PUNCTUATION_N = "\n";
+
+ String[] expectedTokens = new String[] {
+ "Однажды", PUNCTUATION_COMA, PUNCTUATION_SPACE, "в", PUNCTUATION_SPACE, "студеную", PUNCTUATION_SPACE, "зимнюю", PUNCTUATION_SPACE, "пору", PUNCTUATION_N,
+ "Я", " ", "из", " ", "лесу", " ", "вышел", ";", " ", "был", " ", "сильный", " ", "мороз", ".", PUNCTUATION_N,
+ "Гляжу", ",", " ", "поднимается", " ", "медленно", " ", "в", " ", "гору", "\n",
+ "Лошадка", ",", " ", "везущая", " ", "хворосту", " ", "воз", ".", "\n",
+ "И", " ", "шествуя", " ", "важно", ",", " ", "в", " ", "спокойствии", " ", "чинном", ",", "\n",
+ "Лошадку", " ", "ведет", " ", "под", " ", "уздцы", " ", "мужичок", "\n",
+ "В", " ", "больших", " ", "сапогах", ",", " ", "в", " ", "полушубке", " ", "овчинном", ",", "\n",
+ "В"," ","больших"," ","рукавицах","…"," ","а"," ","сам"," ","с"," ","ноготок","!","\n",
+ "«","Здорово"," ","парнище","!","»"," ","—"," ","«","Ступай"," ","себе"," ","мимо","!","»","\n",
+ "—"," ","«","Уж"," ","больно"," ","ты"," ","грозен",","," ","как"," ","я"," ","погляжу","!","\n",
+ "Откуда"," ","дровишки","?","»"," ","—"," ","«","Из"," ","лесу",","," ","вестимо",";","\n",
+ "Отец",","," ","слышишь",","," ","рубит",","," ","а"," ","я"," ","отвожу","»",".","\n",
+ "(","В"," ","лесу"," ","раздавался"," ","топор"," ","дровосека",".",")","\n",
+ "«","А"," ","что",","," ","у"," ","отца-то"," ","большая"," ","семья","?","»","\n",
+ "—"," ","«","Семья-то"," ","большая",","," ","да"," ","два"," ","человека","\n",
+ "Всего"," ","мужиков-то",":"," ","отец"," ","мой"," ","да"," ","я","…","»","\n",
+ "—"," ","«","Так"," ","вот"," ","оно"," ","что","!"," ","А"," ","как"," ","звать"," ","тебя","?","»"," ","—"," ","«","Власом","»",".","\n",
+ "—"," ","«","А"," ","кой-тебе"," ","годик","?","»"," ","—"," ","«","Шестой"," ","миновал","…","\n",
+ "Ну",","," ","мертвая","!","»"," ","—"," ","крикнул"," ","малюточка"," ","басом",",","\n",
+ "Рванул"," ","под"," ","уздцы"," ","и"," ","быстрей"," ","зашагал","."
+ };
+
+ GenericTokenizer tokenizer = new GenericTokenizer();
+ String[] actualTokens = tokenizer.tokenizeString(inputString);
+
+ assertArrayEquals(expectedTokens, actualTokens);
+ }
+
+}
diff --git a/images/allicons.svg b/images/allicons.svg
index 1055987..e5726c9 100644
--- a/images/allicons.svg
+++ b/images/allicons.svg
@@ -9,7 +9,7 @@
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="allicons.svg"
- inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
+ inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
id="svg8"
version="1.1"
viewBox="0 0 210 297"
@@ -30,35 +30,22 @@
stdDeviation="0.00078338267"
inkscape:collect="always" />
-
-
-
+ position="2.9207403,295.28566"
+ inkscape:locked="true" />
+ position="21.524586,292.23793"
+ inkscape:locked="true" />
+ position="10.286085,275.79289"
+ inkscape:locked="true" />
+ position="13.643008,294.39377"
+ inkscape:locked="true" />
@@ -91,7 +82,7 @@
image/svg+xml
-
+
@@ -102,113 +93,7 @@
inkscape:label="bg">
+ d="m 27.317905,-12.461092 h -10 v -4 h 10 m -3,13.9999997 a 3,3 0 0 1 -3,-3 3,3 0 0 1 3,-2.9999999 3,3 0 0 1 3,2.9999999 3,3 0 0 1 -3,3 m 5,-15.9999997 h -12 c -1.11,0 -2,0.9 -2,2 v 13.9999997 a 2,2 0 0 0 2,2.00000005 h 14 a 2,2 0 0 0 2,-2.00000005 V -14.461092 Z"
+ style="fill:none;stroke:#000000;stroke-width:0.26458299px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+
+
+