From 90d2cb40b9fc298af7daad9c1351fe7500a33d61 Mon Sep 17 00:00:00 2001 From: dgis Date: Wed, 3 Jul 2019 21:55:34 +0200 Subject: [PATCH] Improve source code --- ReadMe.txt | 2 +- app/CMakeLists.txt | 2 +- .../emulator/calculator/PrinterSimulator.java | 15 +- .../calculator/PrinterSimulatorFragment.java | 2 +- .../emulator/forty/eight/MainActivity.java | 189 ++++++++++-------- app/src/main/res/values/strings.xml | 4 +- app/src/main/res/xml/pref_general.xml | 5 + 7 files changed, 134 insertions(+), 85 deletions(-) diff --git a/ReadMe.txt b/ReadMe.txt index 1412e8a..7287ebb 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -56,7 +56,7 @@ CHANGES Version 1.5 (2019-06-xx) -- Add the Ir printer simulator (set delay to 0 to speed up!). +- Add the Ir printer simulator based on the Christoph Giesselink's HP82240B Printer Simulator for Windows. - Add the macro support. - Refactor the code for easier code sharing between Emu48, Emu42 and Emu71. - Fix: Bad text characters when copy/paste the stack. diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index c2cca8c..f5e9f39 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -12,7 +12,7 @@ cmake_minimum_required(VERSION 3.4.1) #add_compile_options(-DDEBUG_IO) #add_compile_options(-DDEBUG_SERIAL) -add_compile_options(-DDEBUG_ANDROID_WAVE_OUT) +#add_compile_options(-DDEBUG_ANDROID_WAVE_OUT) #add_compile_options(-DDEBUG_ANDROID_TIMER) #add_compile_options(-DDEBUG_ANDROID_PAINT) #add_compile_options(-DDEBUG_ANDROID_THREAD) diff --git a/app/src/main/java/org/emulator/calculator/PrinterSimulator.java b/app/src/main/java/org/emulator/calculator/PrinterSimulator.java index b8e7e37..6e3a7de 100644 --- a/app/src/main/java/org/emulator/calculator/PrinterSimulator.java +++ b/app/src/main/java/org/emulator/calculator/PrinterSimulator.java @@ -25,6 +25,7 @@ import java.util.ArrayList; public class PrinterSimulator { private static final String TAG = "PrinterSimulator"; + private boolean debug = false; private ArrayList data = new ArrayList<>(); private StringBuilder m_Text = new StringBuilder(); private StringBuilder textUpdate = new StringBuilder(); @@ -70,6 +71,15 @@ public class PrinterSimulator { m_bPrinter82240A = enable; } + /** + * true to prevent the line wrapping for the textual printer when the character '\4' is sent by the calc. + * @param preventLineWrap true to prevent the line wrapping; false otherwise. + */ + public void setPreventLineWrap(boolean preventLineWrap) { + this.preventLineWrap = preventLineWrap; + } + + /** * Change the paper, so we cleanup everything. */ @@ -245,6 +255,8 @@ public class PrinterSimulator { // Text Printer + private boolean preventLineWrap = false; + /** * ROMAN8 Unicode table */ @@ -294,9 +306,10 @@ public class PrinterSimulator { private void addTextData(int byData) { do { // special LF and LF characters - if (byData == 0x04 || byData == 0x0A) { + if (!preventLineWrap && byData == 0x04 || byData == 0x0A) { textUpdate.append('\r'); textUpdate.append('\n'); + if(debug) Log.d(TAG, "addTextData(" + byData + ")"); break; } diff --git a/app/src/main/java/org/emulator/calculator/PrinterSimulatorFragment.java b/app/src/main/java/org/emulator/calculator/PrinterSimulatorFragment.java index 791c5d9..78474c2 100644 --- a/app/src/main/java/org/emulator/calculator/PrinterSimulatorFragment.java +++ b/app/src/main/java/org/emulator/calculator/PrinterSimulatorFragment.java @@ -277,7 +277,7 @@ public class PrinterSimulatorFragment extends AppCompatDialogFragment { private void commonInitialization() { setShowScaleThumbnail(true); - scaleThumbnailColor = Color.RED; + scaleThumbnailColor = Color.GRAY; } public void setBitmap(Bitmap bitmap) { diff --git a/app/src/main/java/org/emulator/forty/eight/MainActivity.java b/app/src/main/java/org/emulator/forty/eight/MainActivity.java index 721c641..bc74729 100644 --- a/app/src/main/java/org/emulator/forty/eight/MainActivity.java +++ b/app/src/main/java/org/emulator/forty/eight/MainActivity.java @@ -67,6 +67,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; @@ -178,7 +179,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On Set savedMRU = sharedPreferences.getStringSet("MRU", null); if(savedMRU != null) { for (String url : savedMRU) { - if(url != null & !url.isEmpty()) + if(url != null && !url.isEmpty()) mruLinkedHashMap.put(url, null); } } @@ -335,7 +336,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On @Override public boolean onNavigationItemSelected(MenuItem item) { // Handle navigation view item clicks here. - int id = item.getItemId(); + int id = item != null ? item.getItemId() : -1; if (id == R.id.nav_new) { OnFileNew(); } else if (id == R.id.nav_open) { @@ -465,7 +466,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On if (calculatorFilename.toLowerCase().lastIndexOf(".kml") != -1) { BufferedReader reader = null; try { - reader = new BufferedReader(new InputStreamReader(assetManager.open("calculators/" + calculatorFilename), "UTF-8")); + reader = new BufferedReader(new InputStreamReader(assetManager.open("calculators/" + calculatorFilename), StandardCharsets.UTF_8)); // do reading, usually loop until end of file reading String mLine; boolean inGlobal = false; @@ -519,14 +520,16 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On List calculatorsAssetFilenames = new LinkedList<>(); DocumentFile kmlFolderDocumentFile = DocumentFile.fromTreeUri(this, kmlFolderUri); - for (DocumentFile file : kmlFolderDocumentFile.listFiles()) { - final String url = file.getUri().toString(); - final String name = file.getName(); - final String mime = file.getType(); - Log.d(TAG, "url: " + url + ", name: " + name + ", mime: " + mime); - if(kmlMimeType.equals(mime)) { - calculatorsAssetFilenames.add(url); - } + if(kmlFolderDocumentFile != null) { + for (DocumentFile file : kmlFolderDocumentFile.listFiles()) { + final String url = file.getUri().toString(); + final String name = file.getName(); + final String mime = file.getType(); + Log.d(TAG, "url: " + url + ", name: " + name + ", mime: " + mime); + if(kmlMimeType.equals(mime)) { + calculatorsAssetFilenames.add(url); + } + } } kmlScripts.clear(); Pattern patternGlobalTitle = Pattern.compile("\\s*Title\\s+\"(.*)\""); @@ -538,41 +541,43 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On try { Uri calculatorsAssetFilenameUri = Uri.parse(calculatorFilename); DocumentFile documentFile = DocumentFile.fromSingleUri(this, calculatorsAssetFilenameUri); - Uri fileUri = documentFile.getUri(); - InputStream inputStream = getContentResolver().openInputStream(fileUri); - reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); - // do reading, usually loop until end of file reading - String mLine; - boolean inGlobal = false; - String title = null; - String model = null; - while ((mLine = reader.readLine()) != null) { - //process line - if (mLine.indexOf("Global") == 0) { - inGlobal = true; - title = null; - model = null; - continue; - } - if (inGlobal) { - if (mLine.indexOf("End") == 0) { - KMLScriptItem newKMLScriptItem = new KMLScriptItem(); - newKMLScriptItem.filename = kmlFolderUseDefault ? calculatorFilename : "document:" + kmlFolderURL + "|" + calculatorFilename; - newKMLScriptItem.title = title; - newKMLScriptItem.model = model; - kmlScripts.add(newKMLScriptItem); - break; - } - - m = patternGlobalTitle.matcher(mLine); - if (m.find()) { - title = m.group(1); - } - m = patternGlobalModel.matcher(mLine); - if (m.find()) { - model = m.group(1); - } - } + if(documentFile != null) { + Uri fileUri = documentFile.getUri(); + InputStream inputStream = getContentResolver().openInputStream(fileUri); + reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); + // do reading, usually loop until end of file reading + String mLine; + boolean inGlobal = false; + String title = null; + String model = null; + while ((mLine = reader.readLine()) != null) { + //process line + if (mLine.indexOf("Global") == 0) { + inGlobal = true; + title = null; + model = null; + continue; + } + if (inGlobal) { + if (mLine.indexOf("End") == 0) { + KMLScriptItem newKMLScriptItem = new KMLScriptItem(); + newKMLScriptItem.filename = kmlFolderUseDefault ? calculatorFilename : "document:" + kmlFolderURL + "|" + calculatorFilename; + newKMLScriptItem.title = title; + newKMLScriptItem.model = model; + kmlScripts.add(newKMLScriptItem); + break; + } + + m = patternGlobalTitle.matcher(mLine); + if (m.find()) { + title = m.group(1); + } + m = patternGlobalModel.matcher(mLine); + if (m.find()) { + model = m.group(1); + } + } + } } } catch (IOException e) { //log the exception @@ -852,7 +857,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On final ArrayList kmlScriptsForCurrentModel; if(changeKML) { - kmlScriptsForCurrentModel = new ArrayList(); + kmlScriptsForCurrentModel = new ArrayList<>(); char m = (char) NativeLib.getCurrentModel(); for (int i = 0; i < kmlScripts.size(); i++) { KMLScriptItem kmlScriptItem = kmlScripts.get(i); @@ -1037,7 +1042,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On if (openResult > 0) { saveLastDocument(url); makeUriPersistable(data, uri); - } else if(openResult == -2) { + } else if(openResult == -2 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // >= API 21 // For security reason, you must select the folder where are the KML and ROM files and then, reopen this file! new AlertDialog.Builder(this) .setTitle(getString(R.string.message_open_security)) @@ -1110,16 +1115,18 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On //Log.d(TAG, "onActivityResult INTENT_CREATE_RAM_CARD " + url); if(selectedRAMSize > 0) { int size = 2 * selectedRAMSize; - FileOutputStream fileOutputStream = null; + FileOutputStream fileOutputStream; try { ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(uri, "w"); - fileOutputStream = new FileOutputStream(pfd.getFileDescriptor()); - byte[] zero = new byte[1024]; - Arrays.fill(zero, (byte) 0); - for (int i = 0; i < size; i++) - fileOutputStream.write(zero); - fileOutputStream.flush(); - fileOutputStream.close(); + if(pfd != null) { + fileOutputStream = new FileOutputStream(pfd.getFileDescriptor()); + byte[] zero = new byte[1024]; + Arrays.fill(zero, (byte) 0); + for (int i = 0; i < size; i++) + fileOutputStream.write(zero); + fileOutputStream.flush(); + fileOutputStream.close(); + } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { @@ -1246,10 +1253,12 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On }).show(); } + // Method used from JNI! + final int GENERIC_READ = 1; final int GENERIC_WRITE = 2; Map parcelFileDescriptorPerFd = null; - int openFileFromContentResolver(String fileURL, int writeAccess) { + public int openFileFromContentResolver(String fileURL, int writeAccess) { //https://stackoverflow.com/a/31677287 Uri uri = Uri.parse(fileURL); ParcelFileDescriptor filePfd; @@ -1274,20 +1283,22 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On parcelFileDescriptorPerFd.put(fd, filePfd); return fd; } - int openFileInFolderFromContentResolver(String filename, String folderURL, int writeAccess) { + public int openFileInFolderFromContentResolver(String filename, String folderURL, int writeAccess) { Uri folderURI = Uri.parse(folderURL); DocumentFile folderDocumentFile = DocumentFile.fromTreeUri(this, folderURI); - for (DocumentFile file : folderDocumentFile.listFiles()) { - final String url = file.getUri().toString(); - final String name = file.getName(); - //Log.d(TAG, "url: " + url + ", name: " + name); - if(filename.equals(name)) { - return openFileFromContentResolver(url, writeAccess); + if(folderDocumentFile != null) { + for (DocumentFile file : folderDocumentFile.listFiles()) { + final String url = file.getUri().toString(); + final String name = file.getName(); + //Log.d(TAG, "url: " + url + ", name: " + name); + if (filename.equals(name)) { + return openFileFromContentResolver(url, writeAccess); + } } } return -1; } - int closeFileFromContentResolver(int fd) { + public int closeFileFromContentResolver(int fd) { if(parcelFileDescriptorPerFd != null) { ParcelFileDescriptor filePfd = parcelFileDescriptorPerFd.get(fd); if(filePfd != null) { @@ -1307,7 +1318,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On Utils.showAlert(this, text); } - void sendMenuItemCommand(int menuItem) { + public void sendMenuItemCommand(int menuItem) { switch (menuItem) { case 1: // FILE_NEW OnFileNew(); @@ -1385,7 +1396,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On } } - String getFirstKMLFilenameForType(char chipsetType) { + public String getFirstKMLFilenameForType(char chipsetType) { extractKMLScripts(); for (int i = 0; i < kmlScripts.size(); i++) { @@ -1411,7 +1422,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On return null; } - void clipboardCopyText(String text) { + public void clipboardCopyText(String text) { // Gets a handle to the clipboard service. ClipboardManager clipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE); if(clipboard != null) { @@ -1420,7 +1431,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On clipboard.setPrimaryClip(clip); } } - String clipboardPasteText() { + public String clipboardPasteText() { ClipboardManager clipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE); if (clipboard != null && clipboard.hasPrimaryClip()) { ClipData clipData = clipboard.getPrimaryClip(); @@ -1435,12 +1446,12 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On return ""; } - void performHapticFeedback() { + public void performHapticFeedback() { if(sharedPreferences.getBoolean("settings_haptic_feedback", true)) mainScreenView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); } - void sendByteUdp(int byteSent) { + public void sendByteUdp(int byteSent) { printerSimulator.write(byteSent); } @@ -1458,7 +1469,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On String[] settingKeys = { "settings_realspeed", "settings_grayscale", "settings_rotation", "settings_auto_layout", "settings_hide_bar", "settings_hide_button_menu", "settings_sound_volume", "settings_haptic_feedback", - "settings_background_kml_color", "settings_background_fallback_color", "settings_printer_model", "settings_macro", + "settings_background_kml_color", "settings_background_fallback_color", + "settings_printer_model", "settings_printer_prevent_line_wrap", "settings_macro", "settings_kml", "settings_port1", "settings_port2" }; for (String settingKey : settingKeys) { updateFromPreferences(settingKey, false); @@ -1475,15 +1487,23 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On case "settings_rotation": int rotationMode = 0; try { - rotationMode = Integer.parseInt(sharedPreferences.getString("settings_rotation", "0")); - } catch (NumberFormatException ex) {} + String rotationModeValue = sharedPreferences.getString("settings_rotation", "0"); + if(rotationModeValue != null) + rotationMode = Integer.parseInt(rotationModeValue); + } catch (NumberFormatException ex) { + // Catch bad number format + } mainScreenView.setRotationMode(rotationMode, isDynamic); break; case "settings_auto_layout": int autoLayoutMode = 1; try { - autoLayoutMode = Integer.parseInt(sharedPreferences.getString("settings_auto_layout", "1")); - } catch (NumberFormatException ex) {} + String autoLayoutModeValue = sharedPreferences.getString("settings_auto_layout", "1"); + if(autoLayoutModeValue != null) + autoLayoutMode = Integer.parseInt(autoLayoutModeValue); + } catch (NumberFormatException ex) { + // Catch bad number format + } mainScreenView.setAutoLayout(autoLayoutMode, isDynamic); break; case "settings_hide_bar": @@ -1514,14 +1534,23 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On case "settings_background_fallback_color": String fallbackColor = sharedPreferences.getString("settings_background_fallback_color", "0"); try { - mainScreenView.setBackgroundFallbackColor(Integer.parseInt(fallbackColor)); - } catch (NumberFormatException ex) {} + if(fallbackColor != null) + mainScreenView.setBackgroundFallbackColor(Integer.parseInt(fallbackColor)); + } catch (NumberFormatException ex) { + // Catch bad number format + } break; case "settings_printer_model": String printerModel = sharedPreferences.getString("settings_printer_model", "1"); try { - printerSimulator.setPrinterModel82240A(Integer.parseInt(printerModel) == 0); - } catch (NumberFormatException ex) {} + if(printerModel != null) + printerSimulator.setPrinterModel82240A(Integer.parseInt(printerModel) == 0); + } catch (NumberFormatException ex) { + // Catch bad number format + } + break; + case "settings_printer_prevent_line_wrap": + printerSimulator.setPreventLineWrap(sharedPreferences.getBoolean("settings_printer_prevent_line_wrap", false)); break; case "settings_kml": diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9dc8d20..05047c6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -83,7 +83,7 @@ Printer Simulator Save printer paper as text Save printer paper as image - Out of paper error for the graphic printer (max line: %s, max pixel line: %s). + Out of paper error for the graphic printer (max line: %d, max pixel line: %d). @@ -125,6 +125,8 @@ Printer Simulator Printer Model You can choose the printer model + Prevent Line Wrapping + Prevent the calc to wrap the line in the textual printer simulator Macro Use Real Replay Speed diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml index 627d77e..4119483 100644 --- a/app/src/main/res/xml/pref_general.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -106,6 +106,11 @@ android:entryValues="@array/settings_printer_model_value" android:defaultValue="1" /> +