diff --git a/APDE/src/main/java/com/calsignlabs/apde/EditorActivity.java b/APDE/src/main/java/com/calsignlabs/apde/EditorActivity.java index 3757c17..bbdda38 100644 --- a/APDE/src/main/java/com/calsignlabs/apde/EditorActivity.java +++ b/APDE/src/main/java/com/calsignlabs/apde/EditorActivity.java @@ -1759,6 +1759,53 @@ public void launchRenameSketch() { } dialog.show(); } + + /** + * Open the duplicate sketch AlertDialog + */ + public void launchDuplicateSketch() { + AlertDialog.Builder alert = new AlertDialog.Builder(this); + + alert.setTitle(String.format(Locale.US, getResources().getString(R.string.duplicate_sketch_title), getGlobalState().getSketchName())); + alert.setMessage(R.string.duplicate_sketch_message); + + final EditText input = getGlobalState().createAlertDialogEditText(this, alert, getGlobalState().getSketchName(), true); + + alert.setPositiveButton(R.string.duplicate_sketch_button, (dialog, whichButton) -> { + String sketchName = input.getText().toString(); + + try { + if (validateSketchName(sketchName) && !sketchName.equals(getGlobalState().getSketchName())) { + APDE.SketchMeta source = new APDE.SketchMeta(getGlobalState().getSketchLocationType(), getGlobalState().getSketchPath()); + APDE.SketchMeta dest = new APDE.SketchMeta(source.getLocation(), source.getParent() + "/" + sketchName); + + getGlobalState().copyFolder(source, dest, EditorActivity.this); + + getGlobalState().setSketchName(sketchName); + updateSketchPath("/" + sketchName); + } + + if (!PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean("use_hardware_keyboard", false)) { + ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(input.getWindowToken(), 0); + } + } catch (MaybeDocumentFile.MaybeDocumentFileException | FileNotFoundException e) { + e.printStackTrace(); + } + }); + + alert.setNegativeButton(R.string.cancel, (dialog, whichButton) -> { + if (!PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean("use_hardware_keyboard", false)) { + ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(input.getWindowToken(), 0); + } + }); + + // Show the soft keyboard if the hardware keyboard is unavailable (hopefully) + AlertDialog dialog = alert.create(); + if (!PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean("use_hardware_keyboard", false)) { + dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + } + dialog.show(); + } /** * Called when the user selects "Load Sketch" - this will open the navigation drawer @@ -2795,9 +2842,11 @@ public boolean onLongClick(View v) { menu.findItem(R.id.menu_redo).setVisible(false); menu.findItem(R.id.menu_tab_delete).setVisible(false); menu.findItem(R.id.menu_tab_rename).setVisible(false); + menu.findItem(R.id.menu_tab_duplicate).setVisible(false); menu.findItem(R.id.menu_save).setVisible(false); menu.findItem(R.id.menu_delete).setVisible(false); menu.findItem(R.id.menu_rename).setVisible(false); + menu.findItem(R.id.menu_duplicate).setVisible(false); menu.findItem(R.id.menu_copy_to_sketchbook).setVisible(false); menu.findItem(R.id.menu_move_to_sketchbook).setVisible(false); menu.findItem(R.id.menu_new).setVisible(false); @@ -2816,6 +2865,7 @@ public boolean onLongClick(View v) { menu.findItem(R.id.menu_run).setVisible(true); menu.findItem(R.id.menu_tab_delete).setVisible(true); menu.findItem(R.id.menu_tab_rename).setVisible(true); + menu.findItem(R.id.menu_tab_duplicate).setVisible(true); menu.findItem(R.id.menu_tools).setVisible(true); @@ -2841,6 +2891,7 @@ public boolean onLongClick(View v) { menu.findItem(R.id.menu_redo).setVisible(false); menu.findItem(R.id.menu_tab_delete).setVisible(false); menu.findItem(R.id.menu_tab_rename).setVisible(false); + menu.findItem(R.id.menu_tab_duplicate).setVisible(false); menu.findItem(R.id.menu_tools).setVisible(false); } @@ -2856,6 +2907,7 @@ public boolean onLongClick(View v) { menu.findItem(R.id.menu_save).setVisible(true); menu.findItem(R.id.menu_delete).setVisible(true); menu.findItem(R.id.menu_rename).setVisible(true); + menu.findItem(R.id.menu_duplicate).setVisible(true); menu.findItem(R.id.menu_copy_to_sketchbook).setVisible(false); menu.findItem(R.id.menu_move_to_sketchbook).setVisible(false); break; @@ -2863,6 +2915,7 @@ public boolean onLongClick(View v) { menu.findItem(R.id.menu_save).setVisible(true); menu.findItem(R.id.menu_delete).setVisible(true); menu.findItem(R.id.menu_rename).setVisible(false); + menu.findItem(R.id.menu_duplicate).setVisible(false); menu.findItem(R.id.menu_copy_to_sketchbook).setVisible(false); menu.findItem(R.id.menu_move_to_sketchbook).setVisible(true); break; @@ -2870,6 +2923,7 @@ public boolean onLongClick(View v) { menu.findItem(R.id.menu_save).setVisible(true); menu.findItem(R.id.menu_delete).setVisible(true); menu.findItem(R.id.menu_rename).setVisible(true); + menu.findItem(R.id.menu_duplicate).setVisible(true); menu.findItem(R.id.menu_copy_to_sketchbook).setVisible(true); menu.findItem(R.id.menu_move_to_sketchbook).setVisible(false); break; @@ -2878,6 +2932,7 @@ public boolean onLongClick(View v) { menu.findItem(R.id.menu_save).setVisible(false); menu.findItem(R.id.menu_delete).setVisible(false); menu.findItem(R.id.menu_rename).setVisible(false); + menu.findItem(R.id.menu_duplicate).setVisible(false); menu.findItem(R.id.menu_copy_to_sketchbook).setVisible(true); menu.findItem(R.id.menu_move_to_sketchbook).setVisible(false); break; @@ -2897,6 +2952,7 @@ public boolean onLongClick(View v) { menu.findItem(R.id.menu_tab_new).setVisible(false); menu.findItem(R.id.menu_tab_delete).setVisible(false); menu.findItem(R.id.menu_tab_rename).setVisible(false); + menu.findItem(R.id.menu_tab_duplicate).setVisible(false); // With auto-saving, we don't actually need to let the user save the sketch manually // However, the keyboard shortcut will still be available @@ -2997,6 +3053,9 @@ public boolean onOptionsItemSelected(MenuItem item) { case R.id.menu_rename: launchRenameSketch(); return true; + case R.id.menu_duplicate: + launchDuplicateSketch(); + return true; case R.id.menu_copy_to_sketchbook: copyToSketchbook(); return true; @@ -3021,6 +3080,9 @@ public boolean onOptionsItemSelected(MenuItem item) { case R.id.menu_tab_rename: renameTab(); return true; + case R.id.menu_tab_duplicate: + duplicateTab(); + return true; case R.id.menu_tab_delete: deleteTab(); return true; @@ -3999,6 +4061,9 @@ public boolean onMenuItemClick(MenuItem item) { case R.id.menu_tab_rename: renameTab(); return true; + case R.id.menu_tab_duplicate: + duplicateTab(); + return true; case R.id.menu_tab_delete: deleteTab(); return true; @@ -4107,6 +4172,14 @@ private void renameTab() { createInputDialog(getResources().getString(R.string.tab_rename_dialog_title), getResources().getString(R.string.tab_rename_dialog_message), getSelectedSketchFile().getTitle(), RENAME_TAB); } + /** + * Creates a user input dialog for duplicating the current tab + */ + private void duplicateTab() { + if(tabs.size() > 0 && !getGlobalState().isExample()) + createInputDialog(getResources().getString(R.string.tab_duplicate_dialog_title), getResources().getString(R.string.tab_duplicate_dialog_message), getSelectedSketchFile().getTitle(), DUPLICATE_TAB); + } + /** * Creates a user input dialog for deleting the current tab */ diff --git a/APDE/src/main/res/menu/activity_editor.xml b/APDE/src/main/res/menu/activity_editor.xml index d0c63a8..ce03834 100644 --- a/APDE/src/main/res/menu/activity_editor.xml +++ b/APDE/src/main/res/menu/activity_editor.xml @@ -85,6 +85,10 @@ android:id="@+id/menu_rename" app:showAsAction="never" android:title="@string/editor_menu_rename_sketch" /> + @@ -96,6 +100,10 @@ android:id="@+id/menu_tab_rename" app:showAsAction="never" android:title="@string/editor_menu_tab_rename" /> + - \ No newline at end of file + diff --git a/APDE/src/main/res/menu/tab_actions.xml b/APDE/src/main/res/menu/tab_actions.xml index 2e9f7eb..d4ecca5 100644 --- a/APDE/src/main/res/menu/tab_actions.xml +++ b/APDE/src/main/res/menu/tab_actions.xml @@ -6,7 +6,10 @@ + - \ No newline at end of file + diff --git a/APDE/src/main/res/values/strings.xml b/APDE/src/main/res/values/strings.xml index 0aae536..2d4982a 100644 --- a/APDE/src/main/res/values/strings.xml +++ b/APDE/src/main/res/values/strings.xml @@ -19,6 +19,7 @@ Tools New Sketch Rename Sketch + Duplicate Sketch Delete Sketch Sketch Properties Copy to Sketchbook @@ -28,6 +29,7 @@ New Tab Rename Tab + Duplicate Tab Delete Tab @@ -422,4 +424,4 @@ APDE requires access to the external storage in order to store sketches there. Either grant the required permissions or change the sketchbook location to the internal storage. Grant Permission Use Internal Storage - \ No newline at end of file +