diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index cc18a26c..da11c5e6 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -56,12 +56,12 @@
android:screenOrientation="locked"
android:theme="@style/AppTheme.NoActionBar" />
diff --git a/app/src/main/java/app/notesr/activity/MainActivity.java b/app/src/main/java/app/notesr/activity/MainActivity.java
index 7167f049..0c191b39 100644
--- a/app/src/main/java/app/notesr/activity/MainActivity.java
+++ b/app/src/main/java/app/notesr/activity/MainActivity.java
@@ -19,7 +19,7 @@
import app.notesr.service.AndroidServiceRegistry;
import app.notesr.service.lifecycle.AppCloseAndroidService;
import app.notesr.service.lifecycle.AppCloseAndroidServiceStarter;
-import app.notesr.activity.note.NotesListActivity;
+import app.notesr.activity.note.list.NotesListActivity;
import app.notesr.activity.security.AuthActivity;
import app.notesr.activity.security.KeyRecoveryActivity;
diff --git a/app/src/main/java/app/notesr/activity/exporter/ExportActivity.java b/app/src/main/java/app/notesr/activity/exporter/ExportActivity.java
index 1882bca2..3d22921d 100644
--- a/app/src/main/java/app/notesr/activity/exporter/ExportActivity.java
+++ b/app/src/main/java/app/notesr/activity/exporter/ExportActivity.java
@@ -46,7 +46,7 @@
import app.notesr.service.exporter.ExportAndroidServiceStarter;
import app.notesr.service.exporter.ExportStatus;
import app.notesr.service.file.FileService;
-import app.notesr.activity.note.NotesListActivity;
+import app.notesr.activity.note.list.NotesListActivity;
import app.notesr.service.note.NoteService;
import app.notesr.util.VersionFetcherImpl;
diff --git a/app/src/main/java/app/notesr/activity/file/FilesListActivity.java b/app/src/main/java/app/notesr/activity/file/FilesListActivity.java
index 3f1e63c5..d22d021a 100644
--- a/app/src/main/java/app/notesr/activity/file/FilesListActivity.java
+++ b/app/src/main/java/app/notesr/activity/file/FilesListActivity.java
@@ -30,7 +30,7 @@
import app.notesr.activity.DialogFactory;
import app.notesr.data.AppDatabase;
import app.notesr.data.DatabaseProvider;
-import app.notesr.activity.note.OpenNoteActivity;
+import app.notesr.activity.note.editor.OpenNoteActivity;
import app.notesr.service.file.FileService;
import app.notesr.service.note.NoteService;
import app.notesr.data.model.FileInfo;
diff --git a/app/src/main/java/app/notesr/activity/importer/ImportActivity.java b/app/src/main/java/app/notesr/activity/importer/ImportActivity.java
index 4e945e12..2af93957 100644
--- a/app/src/main/java/app/notesr/activity/importer/ImportActivity.java
+++ b/app/src/main/java/app/notesr/activity/importer/ImportActivity.java
@@ -28,7 +28,7 @@
import app.notesr.R;
import app.notesr.activity.ActivityBase;
-import app.notesr.activity.note.NotesListActivity;
+import app.notesr.activity.note.list.NotesListActivity;
import app.notesr.service.AndroidServiceRegistry;
import app.notesr.service.importer.ImportAndroidService;
import app.notesr.service.importer.ImportAndroidServiceStarter;
diff --git a/app/src/main/java/app/notesr/activity/migration/MigrationActivity.java b/app/src/main/java/app/notesr/activity/migration/MigrationActivity.java
index 12340d47..061ec9c5 100644
--- a/app/src/main/java/app/notesr/activity/migration/MigrationActivity.java
+++ b/app/src/main/java/app/notesr/activity/migration/MigrationActivity.java
@@ -14,7 +14,7 @@
import app.notesr.BuildConfig;
import app.notesr.R;
import app.notesr.activity.ActivityBase;
-import app.notesr.activity.note.NotesListActivity;
+import app.notesr.activity.note.list.NotesListActivity;
import app.notesr.service.AndroidServiceRegistry;
import app.notesr.service.migration.AppMigrationAndroidService;
import app.notesr.service.migration.AppMigrationAndroidServiceStarter;
diff --git a/app/src/main/java/app/notesr/activity/note/DeleteNoteOnClick.java b/app/src/main/java/app/notesr/activity/note/editor/DeleteNoteAction.java
similarity index 88%
rename from app/src/main/java/app/notesr/activity/note/DeleteNoteOnClick.java
rename to app/src/main/java/app/notesr/activity/note/editor/DeleteNoteAction.java
index 6903e238..f02e6332 100644
--- a/app/src/main/java/app/notesr/activity/note/DeleteNoteOnClick.java
+++ b/app/src/main/java/app/notesr/activity/note/editor/DeleteNoteAction.java
@@ -3,29 +3,27 @@
* SPDX-License-Identifier: MIT
*/
-package app.notesr.activity.note;
+package app.notesr.activity.note.editor;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
-import android.view.MenuItem;
-
-import androidx.annotation.NonNull;
import java.io.IOException;
import app.notesr.R;
import app.notesr.activity.ActivityBase;
import app.notesr.activity.DialogFactory;
+import app.notesr.activity.note.list.NotesListActivity;
import app.notesr.data.model.Note;
import app.notesr.service.file.FileService;
import app.notesr.service.note.NoteService;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
-public final class DeleteNoteOnClick implements MenuItem.OnMenuItemClickListener {
+final class DeleteNoteAction {
private final ActivityBase activity;
private final Note note;
@@ -33,8 +31,7 @@ public final class DeleteNoteOnClick implements MenuItem.OnMenuItemClickListener
private final FileService fileService;
private final DialogFactory dialogFactory;
- @Override
- public boolean onMenuItemClick(@NonNull MenuItem item) {
+ void execute() {
DialogInterface.OnClickListener buttonHandler = deleteNoteDialogOnClick();
dialogFactory.getThemedAlertDialogBuilder(R.layout.dialog_action_cannot_be_undo)
.setTitle(R.string.warning)
@@ -42,8 +39,6 @@ public boolean onMenuItemClick(@NonNull MenuItem item) {
.setNegativeButton(R.string.no, buttonHandler)
.create()
.show();
-
- return true;
}
private DialogInterface.OnClickListener deleteNoteDialogOnClick() {
diff --git a/app/src/main/java/app/notesr/activity/note/OpenFilesListOnClick.java b/app/src/main/java/app/notesr/activity/note/editor/OpenFilesListAction.java
similarity index 54%
rename from app/src/main/java/app/notesr/activity/note/OpenFilesListOnClick.java
rename to app/src/main/java/app/notesr/activity/note/editor/OpenFilesListAction.java
index 5583919c..afe88b4e 100644
--- a/app/src/main/java/app/notesr/activity/note/OpenFilesListOnClick.java
+++ b/app/src/main/java/app/notesr/activity/note/editor/OpenFilesListAction.java
@@ -3,13 +3,9 @@
* SPDX-License-Identifier: MIT
*/
-package app.notesr.activity.note;
+package app.notesr.activity.note.editor;
import android.content.Intent;
-import android.view.MenuItem;
-import android.view.View;
-
-import androidx.annotation.NonNull;
import app.notesr.activity.ActivityBase;
import app.notesr.activity.file.FilesListActivity;
@@ -17,23 +13,12 @@
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
-public final class OpenFilesListOnClick implements MenuItem.OnMenuItemClickListener, View.OnClickListener {
+final class OpenFilesListAction {
private final ActivityBase activity;
private final Note note;
- @Override
- public boolean onMenuItemClick(@NonNull MenuItem item) {
- onClickAction();
- return true;
- }
-
- @Override
- public void onClick(View v) {
- onClickAction();
- }
-
- private void onClickAction() {
+ void execute() {
Intent intent = new Intent(activity.getApplicationContext(), FilesListActivity.class);
intent.putExtra(FilesListActivity.EXTRA_NOTE_ID, note.getId());
diff --git a/app/src/main/java/app/notesr/activity/note/OpenNoteActivity.java b/app/src/main/java/app/notesr/activity/note/editor/OpenNoteActivity.java
similarity index 80%
rename from app/src/main/java/app/notesr/activity/note/OpenNoteActivity.java
rename to app/src/main/java/app/notesr/activity/note/editor/OpenNoteActivity.java
index 794d1c1d..9ef13d40 100644
--- a/app/src/main/java/app/notesr/activity/note/OpenNoteActivity.java
+++ b/app/src/main/java/app/notesr/activity/note/editor/OpenNoteActivity.java
@@ -3,9 +3,10 @@
* SPDX-License-Identifier: MIT
*/
-package app.notesr.activity.note;
+package app.notesr.activity.note.editor;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
@@ -25,6 +26,7 @@
import app.notesr.R;
import app.notesr.activity.ActivityBase;
import app.notesr.activity.DialogFactory;
+import app.notesr.activity.note.list.NotesListActivity;
import app.notesr.data.AppDatabase;
import app.notesr.data.DatabaseProvider;
import app.notesr.service.file.FileService;
@@ -48,23 +50,27 @@
public final class OpenNoteActivity extends ActivityBase {
public static final String EXTRA_NOTE_ID = "noteId";
public static final String EXTRA_NOTE_MODIFIED = "modified";
+ private static final String STATE_OPEN_MODE = "openMode";
private static final long MAX_COUNT_IN_BADGE = 9;
private NoteService noteService;
private FileService fileService;
private Note note;
private ActionBar actionBar;
- private Menu activityMenu;
+ private Menu menu;
private DialogFactory dialogFactory;
- private boolean isNoteModified;
private EditText nameField;
private EditText textField;
private TextView markdownViewer;
private ScrollView markdownViewerContainer;
private Markwon markwon;
- private static final String STATE_OPEN_MODE = "openMode";
+ private SaveNoteAction saveNoteAction;
+ private OpenFilesListAction openFilesListAction;
+ private DeleteNoteAction deleteNoteAction;
+ private boolean isNoteModified;
private OpenNoteMode openMode = OpenNoteMode.EDIT;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -140,6 +146,13 @@ private void prepareViews() {
markdownViewer = findViewById(R.id.markdownViewer);
markdownViewerContainer = findViewById(R.id.markdownViewerContainer);
+ saveNoteAction = new SaveNoteAction(this, note, noteService, dialogFactory,
+ nameField, textField);
+ openFilesListAction = new OpenFilesListAction(this, note);
+ deleteNoteAction = new DeleteNoteAction(this, note, noteService, fileService,
+ dialogFactory);
+
+
nameField.setImeOptions(IME_FLAG_NO_PERSONALIZED_LEARNING);
textField.setImeOptions(IME_FLAG_NO_PERSONALIZED_LEARNING);
@@ -150,7 +163,7 @@ private void prepareViews() {
if (!isNoteModified) {
isNoteModified = true;
- MenuItem saveNoteButton = activityMenu.findItem(R.id.saveNoteButton);
+ MenuItem saveNoteButton = menu.findItem(R.id.saveNoteButton);
saveNoteButton.setVisible(true);
}
@@ -169,7 +182,7 @@ private boolean isNewNote() {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_open_note, menu);
- this.activityMenu = menu;
+ this.menu = menu;
MenuItem changeModeButton = menu.findItem(R.id.changeOpenModeButton);
MenuItem saveNoteButton = menu.findItem(R.id.saveNoteButton);
@@ -181,15 +194,21 @@ public boolean onCreateOptionsMenu(Menu menu) {
return true;
});
- saveNoteButton.setOnMenuItemClickListener(new SaveNoteOnClick(this, note,
- noteService, dialogFactory, nameField, textField));
+ saveNoteButton.setOnMenuItemClickListener((item) -> {
+ saveNoteAction.execute();
+ return true;
+ });
if (!isNewNote()) {
- openFilesListButton.setOnMenuItemClickListener(
- new OpenFilesListOnClick(this, note));
+ openFilesListButton.setOnMenuItemClickListener(item -> {
+ openFilesListAction.execute();
+ return true;
+ });
- deleteNoteButton.setOnMenuItemClickListener(new DeleteNoteOnClick(this, note,
- noteService, fileService, dialogFactory));
+ deleteNoteButton.setOnMenuItemClickListener(item -> {
+ deleteNoteAction.execute();
+ return true;
+ });
setAttachedFilesCountBadge(openFilesListButton);
} else {
@@ -221,30 +240,55 @@ private void setAttachedFilesCountBadge(MenuItem openFilesListButton) {
badge.setText(badgeText);
badge.setVisibility(View.VISIBLE);
- view.setOnClickListener(new OpenFilesListOnClick(this, note));
+ view.setOnClickListener(v -> openFilesListAction.execute());
}
});
});
}
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
- if (isNoteModified) {
- Intent intent = new Intent(getApplicationContext(), NotesListActivity.class);
- startActivity(intent);
- } else {
- finish();
- }
+ backButtonOnClick();
return true;
}
return super.onOptionsItemSelected(item);
}
+ private void backButtonOnClick() {
+ if (isNoteModified) {
+ if (!saveNoteAction.isFormCorrect()) {
+ finish();
+ return;
+ }
+
+ DialogInterface.OnClickListener buttonHandler = (dialog, result) -> {
+ if (result == DialogInterface.BUTTON_POSITIVE) {
+ saveNoteAction.execute();
+ Intent intent = new Intent(getApplicationContext(), NotesListActivity.class);
+ startActivity(intent);
+ } else if (result == DialogInterface.BUTTON_NEUTRAL) {
+ finish();
+ }
+ };
+
+ dialogFactory.getThemedAlertDialogBuilder(R.layout.dialog_unsaved_note_changes)
+ .setTitle(R.string.warning)
+ .setPositiveButton(R.string.save, buttonHandler)
+ .setNeutralButton(R.string.dont_save, buttonHandler)
+ .setNegativeButton(R.string.cancel, null)
+ .create()
+ .show();
+ } else {
+ finish();
+ }
+ }
+
private void changeOpenModeButtonOnClick() {
View anchor = findViewById(R.id.popupMenuAnchor);
PopupMenu popup = new PopupMenu(this, anchor);
diff --git a/app/src/main/java/app/notesr/activity/note/OpenNoteMode.java b/app/src/main/java/app/notesr/activity/note/editor/OpenNoteMode.java
similarity index 92%
rename from app/src/main/java/app/notesr/activity/note/OpenNoteMode.java
rename to app/src/main/java/app/notesr/activity/note/editor/OpenNoteMode.java
index 285bede2..ddf264e1 100644
--- a/app/src/main/java/app/notesr/activity/note/OpenNoteMode.java
+++ b/app/src/main/java/app/notesr/activity/note/editor/OpenNoteMode.java
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: MIT
*/
-package app.notesr.activity.note;
+package app.notesr.activity.note.editor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
diff --git a/app/src/main/java/app/notesr/activity/note/SaveNoteOnClick.java b/app/src/main/java/app/notesr/activity/note/editor/SaveNoteAction.java
similarity index 72%
rename from app/src/main/java/app/notesr/activity/note/SaveNoteOnClick.java
rename to app/src/main/java/app/notesr/activity/note/editor/SaveNoteAction.java
index 718ad2dd..1b0f183a 100644
--- a/app/src/main/java/app/notesr/activity/note/SaveNoteOnClick.java
+++ b/app/src/main/java/app/notesr/activity/note/editor/SaveNoteAction.java
@@ -3,28 +3,26 @@
* SPDX-License-Identifier: MIT
*/
-package app.notesr.activity.note;
+package app.notesr.activity.note.editor;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import android.app.Dialog;
import android.content.Intent;
-import android.view.MenuItem;
import android.widget.EditText;
-import androidx.annotation.NonNull;
-
import java.time.LocalDateTime;
import app.notesr.R;
import app.notesr.activity.ActivityBase;
import app.notesr.activity.DialogFactory;
+import app.notesr.activity.note.list.NotesListActivity;
import app.notesr.data.model.Note;
import app.notesr.service.note.NoteService;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
-public final class SaveNoteOnClick implements MenuItem.OnMenuItemClickListener {
+final class SaveNoteAction {
private final ActivityBase activity;
private final Note note;
@@ -33,14 +31,15 @@ public final class SaveNoteOnClick implements MenuItem.OnMenuItemClickListener {
private final EditText nameField;
private final EditText textField;
- @Override
- public boolean onMenuItemClick(@NonNull MenuItem item) {
- String name = nameField.getText().toString();
- String text = textField.getText().toString();
+ boolean isFormCorrect() {
+ return !nameField.getText().toString().isBlank()
+ && !textField.getText().toString().isBlank();
+ }
- if (!name.isBlank() && !text.isBlank()) {
- note.setName(name);
- note.setText(text);
+ void execute() {
+ if (isFormCorrect()) {
+ note.setName(nameField.getText().toString());
+ note.setText(textField.getText().toString());
note.setUpdatedAt(LocalDateTime.now());
Dialog progressDialog = dialogFactory
@@ -56,7 +55,5 @@ public boolean onMenuItemClick(@NonNull MenuItem item) {
});
});
}
-
- return true;
}
}
diff --git a/app/src/main/java/app/notesr/activity/note/NotesListActivity.java b/app/src/main/java/app/notesr/activity/note/list/NotesListActivity.java
similarity index 98%
rename from app/src/main/java/app/notesr/activity/note/NotesListActivity.java
rename to app/src/main/java/app/notesr/activity/note/list/NotesListActivity.java
index a150d1d4..76c2f564 100644
--- a/app/src/main/java/app/notesr/activity/note/NotesListActivity.java
+++ b/app/src/main/java/app/notesr/activity/note/list/NotesListActivity.java
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: MIT
*/
-package app.notesr.activity.note;
+package app.notesr.activity.note.list;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
@@ -31,6 +31,7 @@
import app.notesr.activity.DialogFactory;
import app.notesr.activity.exporter.ExportActivity;
import app.notesr.activity.importer.ImportActivity;
+import app.notesr.activity.note.editor.OpenNoteActivity;
import app.notesr.activity.security.ChangePasswordOnClick;
import app.notesr.activity.security.GenerateNewKeyOnClick;
import app.notesr.activity.security.LockOnClick;
diff --git a/app/src/main/java/app/notesr/activity/note/NotesListAdapter.java b/app/src/main/java/app/notesr/activity/note/list/NotesListAdapter.java
similarity index 97%
rename from app/src/main/java/app/notesr/activity/note/NotesListAdapter.java
rename to app/src/main/java/app/notesr/activity/note/list/NotesListAdapter.java
index 8e2e63b3..927a13cf 100644
--- a/app/src/main/java/app/notesr/activity/note/NotesListAdapter.java
+++ b/app/src/main/java/app/notesr/activity/note/list/NotesListAdapter.java
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: MIT
*/
-package app.notesr.activity.note;
+package app.notesr.activity.note.list;
import android.content.Context;
import android.view.LayoutInflater;
diff --git a/app/src/main/java/app/notesr/activity/note/OpenNoteOnClick.java b/app/src/main/java/app/notesr/activity/note/list/OpenNoteOnClick.java
similarity index 89%
rename from app/src/main/java/app/notesr/activity/note/OpenNoteOnClick.java
rename to app/src/main/java/app/notesr/activity/note/list/OpenNoteOnClick.java
index d0edafab..4557e8e7 100644
--- a/app/src/main/java/app/notesr/activity/note/OpenNoteOnClick.java
+++ b/app/src/main/java/app/notesr/activity/note/list/OpenNoteOnClick.java
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: MIT
*/
-package app.notesr.activity.note;
+package app.notesr.activity.note.list;
import android.content.Context;
import android.content.Intent;
@@ -12,6 +12,7 @@
import java.util.Map;
+import app.notesr.activity.note.editor.OpenNoteActivity;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
diff --git a/app/src/main/java/app/notesr/activity/security/AuthActivityExtension.java b/app/src/main/java/app/notesr/activity/security/AuthActivityExtension.java
index 5bcf0f6d..c1ddc9e3 100644
--- a/app/src/main/java/app/notesr/activity/security/AuthActivityExtension.java
+++ b/app/src/main/java/app/notesr/activity/security/AuthActivityExtension.java
@@ -26,7 +26,7 @@
import app.notesr.core.security.crypto.CryptoManager;
import app.notesr.activity.migration.MigrationActivity;
import app.notesr.core.security.dto.CryptoSecrets;
-import app.notesr.activity.note.NotesListActivity;
+import app.notesr.activity.note.list.NotesListActivity;
import app.notesr.core.util.SecureStringBuilder;
import app.notesr.service.AndroidServiceBootstrapper;
import app.notesr.service.AndroidServiceRegistry;
diff --git a/app/src/main/java/app/notesr/activity/security/KeySetupCompletionHandler.java b/app/src/main/java/app/notesr/activity/security/KeySetupCompletionHandler.java
index 9ed20a37..194960ff 100644
--- a/app/src/main/java/app/notesr/activity/security/KeySetupCompletionHandler.java
+++ b/app/src/main/java/app/notesr/activity/security/KeySetupCompletionHandler.java
@@ -17,7 +17,7 @@
import app.notesr.BuildConfig;
import app.notesr.activity.migration.MigrationActivity;
-import app.notesr.activity.note.NotesListActivity;
+import app.notesr.activity.note.list.NotesListActivity;
import app.notesr.core.security.SecretCache;
import app.notesr.core.security.dto.CryptoSecrets;
import app.notesr.service.security.crypto.setup.SecretsSetupService;
diff --git a/app/src/main/java/app/notesr/activity/security/ReEncryptionActivity.java b/app/src/main/java/app/notesr/activity/security/ReEncryptionActivity.java
index af067bfd..3b72e397 100644
--- a/app/src/main/java/app/notesr/activity/security/ReEncryptionActivity.java
+++ b/app/src/main/java/app/notesr/activity/security/ReEncryptionActivity.java
@@ -18,7 +18,7 @@
import app.notesr.R;
import app.notesr.activity.ActivityBase;
import app.notesr.activity.DialogFactory;
-import app.notesr.activity.note.NotesListActivity;
+import app.notesr.activity.note.list.NotesListActivity;
import app.notesr.service.AndroidServiceRegistry;
import app.notesr.service.security.crypto.update.SecretsUpdateAndroidService;
import app.notesr.service.security.crypto.update.SecretsUpdateAndroidServiceStarter;
diff --git a/app/src/main/res/layout/activity_note_list.xml b/app/src/main/res/layout/activity_note_list.xml
index 4dc189ca..f2c6e5e8 100644
--- a/app/src/main/res/layout/activity_note_list.xml
+++ b/app/src/main/res/layout/activity_note_list.xml
@@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/activity_background"
- tools:context=".activity.note.NotesListActivity">
+ tools:context=".activity.note.list.NotesListActivity">
+ tools:context=".activity.note.editor.OpenNoteActivity">
+
+
+
+
\ 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 96635754..da303f2d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -79,6 +79,7 @@
Are you sure?
File already exists.\nOverwrite?
Save
+ Don\'t save
Overwrite
Saving canceled
Failed to add all files at once
@@ -109,4 +110,5 @@
Markdown View
Change mode
Invisible popup menu anchor
+ This note has unsaved changes. If you close it now, your changes will be lost.
\ No newline at end of file