diff --git a/omniNotes/build.gradle b/omniNotes/build.gradle index 1fa952a5d..888135c6d 100644 --- a/omniNotes/build.gradle +++ b/omniNotes/build.gradle @@ -158,7 +158,7 @@ dependencies { implementation 'ch.acra:acra-http:5.11.2' implementation 'ch.acra:acra-toast:5.11.2' implementation 'com.github.gabrielemariotti.changeloglib:changelog:2.1.0' - implementation 'com.github.vikramkakkar:SublimePicker:8f573b1cfd' + implementation 'com.github.vikramkakkar:SublimePicker:861620a11d' implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.recyclerview:recyclerview:1.3.2' implementation 'com.android.support:multidex:2.0.1' diff --git a/omniNotes/src/alpha/java/it/feio/android/omninotes/utils/Constants.java b/omniNotes/src/alpha/java/it/feio/android/omninotes/utils/Constants.java index e30a4723f..99e7cd722 100644 --- a/omniNotes/src/alpha/java/it/feio/android/omninotes/utils/Constants.java +++ b/omniNotes/src/alpha/java/it/feio/android/omninotes/utils/Constants.java @@ -15,17 +15,19 @@ * along with this program. If not, see . */ -package it.feio.android.omninotes.utils; + package it.feio.android.omninotes.utils; - -public interface Constants extends ConstantsBase { - - String TAG = "Omni Notes Alpha"; - String EXTERNAL_STORAGE_FOLDER = "Omni Notes Alpha"; - String PACKAGE = "it.feio.android.omninotes.alpha"; - - String CHANNEL_BACKUPS_ID = PACKAGE + ".backups"; - String CHANNEL_REMINDERS_ID = PACKAGE + ".reminders"; - String CHANNEL_PINNED_ID = PACKAGE + ".pinned"; - -} + public final class Constants extends ConstantsBase { + + public static final String TAG = "Omni Notes Alpha"; + public static final String EXTERNAL_STORAGE_FOLDER = "Omni Notes Alpha"; + public static final String PACKAGE = "it.feio.android.omninotes.alpha"; + + public static final String CHANNEL_BACKUPS_ID = PACKAGE + ".backups"; + public static final String CHANNEL_REMINDERS_ID = PACKAGE + ".reminders"; + public static final String CHANNEL_PINNED_ID = PACKAGE + ".pinned"; + + private Constants() { + throw new AssertionError("Cannot be instantiated"); + } + } \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/exceptions/ExceptionsInstrumentationTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/exceptions/ExceptionsInstrumentationTest.java new file mode 100644 index 000000000..dbb36df4f --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/exceptions/ExceptionsInstrumentationTest.java @@ -0,0 +1,56 @@ +package it.feio.android.omninotes.exceptions; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Test; +import org.junit.runner.RunWith; + +import it.feio.android.omninotes.exceptions.unchecked.ExternalDirectoryCreationException; +import it.feio.android.omninotes.exceptions.checked.UnhandledIntentException; + +import static org.junit.Assert.assertThrows; + +@RunWith(AndroidJUnit4.class) +public class ExceptionsInstrumentationTest { + + @Test + public void testGenericException() { + assertThrows(GenericException.class, () -> { + throw new GenericException("Test GenericException"); + }); + } + + @Test + public void testDatabaseException() { + assertThrows(DatabaseException.class, () -> { + throw new DatabaseException("Test DatabaseException", new Exception("Cause")); + }); + } + + @Test + public void testBackupException() { + assertThrows(BackupException.class, () -> { + throw new BackupException("Test BackupException", new Exception("Cause")); + }); + } + + @Test + public void testNotesLoadingException() { + assertThrows(NotesLoadingException.class, () -> { + throw new NotesLoadingException("Test NotesLoadingException", new Exception("Cause")); + }); + } + + @Test + public void testUnhandledIntentException() { + assertThrows(UnhandledIntentException.class, () -> { + throw new UnhandledIntentException(); + }); + } + + @Test + public void testExternalDirectoryCreationException() { + assertThrows(ExternalDirectoryCreationException.class, () -> { + throw new ExternalDirectoryCreationException("Test ExternalDirectoryCreationException"); + }); + } +} \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/factory/MediaStoreFactoryInstrumentationTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/factory/MediaStoreFactoryInstrumentationTest.java new file mode 100644 index 000000000..943ac0cde --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/factory/MediaStoreFactoryInstrumentationTest.java @@ -0,0 +1,48 @@ +package it.feio.android.omninotes.factory; + +import android.net.Uri; +import android.provider.MediaStore; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +@RunWith(AndroidJUnit4.class) +public class MediaStoreFactoryInstrumentationTest { + + private MediaStoreFactory mediaStoreFactory; + + @Before + public void setUp() { + mediaStoreFactory = new MediaStoreFactory(); + } + + @Test + public void testCreateURI_image() { + Uri expectedUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + Uri actualUri = mediaStoreFactory.createURI("image"); + assertEquals("URI should match for image type", expectedUri, actualUri); + } + + @Test + public void testCreateURI_video() { + Uri expectedUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + Uri actualUri = mediaStoreFactory.createURI("video"); + assertEquals("URI should match for video type", expectedUri, actualUri); + } + + @Test + public void testCreateURI_audio() { + Uri expectedUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + Uri actualUri = mediaStoreFactory.createURI("audio"); + assertEquals("URI should match for audio type", expectedUri, actualUri); + } + + @Test + public void testCreateURI_invalidType() { + Uri actualUri = mediaStoreFactory.createURI("invalid"); + assertNull("URI should be null for invalid type", actualUri); + } +} \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/AttachmentsHelperTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/AttachmentsHelperTest.java new file mode 100644 index 000000000..34919b963 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/AttachmentsHelperTest.java @@ -0,0 +1,51 @@ +package it.feio.android.omninotes.helpers; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.net.Uri; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import it.feio.android.omninotes.models.Attachment; +import java.io.File; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class AttachmentsHelperTest { + + private Attachment testAttachment; + + @Before + public void setUp() { + Uri uri = Uri.fromFile(new File("/path/to/test/file")); + testAttachment = new Attachment(uri, "image/jpeg"); + testAttachment.setSize(1024); // Set size to 1KB for testing + } + + @Test + public void testGetSize() { + String expectedSize = "1 KB"; + String actualSize = AttachmentsHelper.getSize(testAttachment); + assertEquals("The size should be 1 KB", expectedSize, actualSize); + } + + @Test + public void testGetSizeWithZeroSize() { + testAttachment.setSize(0); // Simulate a zero size + String actualSize = AttachmentsHelper.getSize(testAttachment); + assertTrue("The size should be greater than 0", actualSize.contains("bytes")); + } + + @Test + public void testTypeOf() { + assertTrue("The attachment should be of type image/jpeg", + AttachmentsHelper.typeOf(testAttachment, "image/jpeg")); + } + + @Test + public void testTypeOfWithMultipleMimeTypes() { + assertTrue("The attachment should be of type image/jpeg or image/png", + AttachmentsHelper.typeOf(testAttachment, "image/jpeg", "image/png")); + } +} \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/NotesHelperInstrumentationTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/NotesHelperInstrumentationTest.java new file mode 100644 index 000000000..e391b4064 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/NotesHelperInstrumentationTest.java @@ -0,0 +1,86 @@ +package it.feio.android.omninotes.helpers; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import it.feio.android.omninotes.models.Attachment; +import it.feio.android.omninotes.models.Note; +import it.feio.android.omninotes.models.StatsSingleNote; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class NotesHelperInstrumentationTest { + + private Context context; + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + } + + @Test + public void testHaveSameId() { + Note note1 = new Note(); + note1.set_id(1L); + Note note2 = new Note(); + note2.set_id(1L); + Note note3 = new Note(); + note3.set_id(2L); + + assertTrue(NotesHelper.haveSameId(note1, note2)); + assertFalse(NotesHelper.haveSameId(note1, note3)); + } + + @Test + public void testMergeNotes() { + Note note1 = new Note(); + note1.setTitle("Title 1"); + note1.setContent("Content 1"); + + Note note2 = new Note(); + note2.setTitle("Title 2"); + note2.setContent("Content 2"); + + List notes = Arrays.asList(note1, note2); + Note mergedNote = NotesHelper.mergeNotes(notes, false); + + assertNotNull(mergedNote); + assertEquals("Title 1", mergedNote.getTitle()); + assertTrue(mergedNote.getContent().contains("Content 1")); + assertTrue(mergedNote.getContent().contains("Content 2")); + } + + @Test + public void testGetNoteInfo() { + Note note = new Note(); + note.setContent("This is a test note with some words."); + + StatsSingleNote info = NotesHelper.getNoteInfo(note); + + assertNotNull(info); + assertEquals(8, info.getWords()); + assertEquals(29, info.getChars()); + } + + @Test + public void testAddAttachments() { + Note note = new Note(); + note.setAttachmentsList(new ArrayList<>()); + + ArrayList attachments = new ArrayList<>(); + NotesHelper.addAttachments(false, note, attachments); + + assertEquals(0, attachments.size()); + } +} \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/count/DefaultWordCounterIntegrationTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/count/DefaultWordCounterIntegrationTest.java new file mode 100644 index 000000000..2eb875122 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/count/DefaultWordCounterIntegrationTest.java @@ -0,0 +1,53 @@ +package it.feio.android.omninotes.helpers.count; + +import static org.junit.Assert.assertEquals; +import it.feio.android.omninotes.models.Note; +import it.feio.android.omninotes.testutils.BaseAndroidTestCase; + +import org.junit.Test; + +public class DefaultWordCounterIntegrationTest extends BaseAndroidTestCase { + + private final String CHECKED_SYM = it.feio.android.checklistview.interfaces.Constants.CHECKED_SYM; + private final String UNCHECKED_SYM = it.feio.android.checklistview.interfaces.Constants.UNCHECKED_SYM; + + @Test + public void testCountWordsWithSimpleText() { + Note note = new Note(); + note.set_id(1L); + note.setTitle("Hello World"); + note.setContent("This is a test note."); + assertEquals(7, new DefaultWordCounter().countWords(note)); + } + + @Test + public void testCountWordsWithChecklist() { + String content = CHECKED_SYM + "Task 1\n" + UNCHECKED_SYM + "Task 2"; + Note note = new Note(); + note.set_id(1L); + note.setTitle("Checklist"); + note.setContent(content); + note.setChecklist(true); + assertEquals(3, new DefaultWordCounter().countWords(note)); + } + + @Test + public void testCountCharsWithSimpleText() { + Note note = new Note(); + note.set_id(1L); + note.setTitle("Hello World"); + note.setContent("This is a test note."); + assertEquals(26, new DefaultWordCounter().countChars(note)); + } + + @Test + public void testCountCharsWithChecklist() { + String content = CHECKED_SYM + "Task 1\n" + UNCHECKED_SYM + "Task 2"; + Note note = new Note(); + note.set_id(1L); + note.setTitle("Checklist"); + note.setContent(content); + note.setChecklist(true); + assertEquals(19, new DefaultWordCounter().countChars(note)); + } +} \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/count/IdeogramsWordCounterIntegrationTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/count/IdeogramsWordCounterIntegrationTest.java new file mode 100644 index 000000000..261f646f1 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/count/IdeogramsWordCounterIntegrationTest.java @@ -0,0 +1,52 @@ +package it.feio.android.omninotes.helpers.count; + +import static org.junit.Assert.assertEquals; + +import it.feio.android.omninotes.models.Note; +import it.feio.android.omninotes.testutils.BaseAndroidTestCase; + +import org.junit.Test; + +public class IdeogramsWordCounterIntegrationTest extends BaseAndroidTestCase { + + private final String CHECKED_SYM = it.feio.android.checklistview.interfaces.Constants.CHECKED_SYM; + private final String UNCHECKED_SYM = it.feio.android.checklistview.interfaces.Constants.UNCHECKED_SYM; + + @Test + public void testCountCharsWithSimpleNote() { + Note note = new Note(); + note.setTitle("这是中文测试"); + note.setContent("這是中文測試\nこれは日本語のテストです"); + IdeogramsWordCounter counter = new IdeogramsWordCounter(); + assertEquals(24, counter.countChars(note)); + } + + @Test + public void testCountCharsWithChecklistNote() { + Note note = new Note(); + note.setTitle("这是中文测试"); + note.setContent(CHECKED_SYM + "這是中文測試\n" + UNCHECKED_SYM + "これは日本語のテストです"); + note.setChecklist(true); + IdeogramsWordCounter counter = new IdeogramsWordCounter(); + assertEquals(24, counter.countChars(note)); + } + + @Test + public void testCountWordsWithSimpleNote() { + Note note = new Note(); + note.setTitle("这是中文测试"); + note.setContent("這是中文測試\nこれは日本語のテストです"); + IdeogramsWordCounter counter = new IdeogramsWordCounter(); + assertEquals(24, counter.countWords(note)); + } + + @Test + public void testCountWordsWithChecklistNote() { + Note note = new Note(); + note.setTitle("这是中文测试"); + note.setContent(CHECKED_SYM + "這是中文測試\n" + UNCHECKED_SYM + "これは日本語のテストです"); + note.setChecklist(true); + IdeogramsWordCounter counter = new IdeogramsWordCounter(); + assertEquals(24, counter.countWords(note)); + } +} \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/date/DateHelperTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/date/DateHelperTest.java new file mode 100644 index 000000000..c52a5def4 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/helpers/date/DateHelperTest.java @@ -0,0 +1,79 @@ +package it.feio.android.omninotes.helpers.date; + +import android.content.Context; +import android.text.format.DateUtils; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import java.util.Locale; +import static org.junit.Assert.assertEquals; + +@RunWith(AndroidJUnit4.class) +public class DateHelperTest { + + private Context context; + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + } + + @Test + public void testGetSortableDate() { + String date = DateHelper.getSortableDate(); + assertEquals(19, date.length()); // yyyyMMdd_HHmmss_SSS + } + + @Test + public void testOnDateSet() { + String formattedDate = DateHelper.onDateSet(2023, 9, 15, "yyyy-MM-dd"); + assertEquals("2023-10-15", formattedDate); + } + + @Test + public void testOnTimeSet() { + String formattedTime = DateHelper.onTimeSet(14, 30, "HH:mm"); + assertEquals("14:30", formattedTime); + } + + @Test + public void testGetDateTimeShort() { + long timestamp = System.currentTimeMillis(); + String formattedDateTime = DateHelper.getDateTimeShort(context, timestamp); + String expected = DateUtils.formatDateTime(context, timestamp, DateUtils.FORMAT_ABBREV_WEEKDAY | DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_MONTH | DateUtils.FORMAT_SHOW_DATE) + " " + DateUtils.formatDateTime(context, timestamp, DateUtils.FORMAT_SHOW_TIME); + assertEquals(expected, formattedDateTime); + } + + @Test + public void testGetTimeShort() { + long timestamp = System.currentTimeMillis(); + String formattedTime = DateHelper.getTimeShort(context, timestamp); + String expected = DateUtils.formatDateTime(context, timestamp, DateUtils.FORMAT_SHOW_TIME); + assertEquals(expected, formattedTime); + } + + @Test + public void testFormatShortTime() { + long timeInMillis = 123456; + String formattedTime = DateHelper.formatShortTime(context, timeInMillis); + assertEquals("2:03", formattedTime); + } + + @Test + public void testGetFormattedDatePrettified() { + long timestamp = System.currentTimeMillis(); + String formattedDate = DateHelper.getFormattedDate(timestamp, true); + // Assuming prettyTime returns a non-null string + assertEquals(it.feio.android.omninotes.utils.date.DateUtils.prettyTime(timestamp), formattedDate); + } + + @Test + public void testGetFormattedDateNotPrettified() { + long timestamp = System.currentTimeMillis(); + String formattedDate = DateHelper.getFormattedDate(timestamp, false); + String expected = DateHelper.getDateTimeShort(context, timestamp); + assertEquals(expected, formattedDate); + } +} \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/models/AttachmentInstrumentationTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/models/AttachmentInstrumentationTest.java new file mode 100644 index 000000000..376015bc9 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/models/AttachmentInstrumentationTest.java @@ -0,0 +1,46 @@ +package it.feio.android.omninotes.models; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import android.net.Uri; +import android.os.Parcel; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Test; +import org.junit.runner.RunWith; + +import it.feio.android.omninotes.commons.models.BaseAttachment; + +@RunWith(AndroidJUnit4.class) +public class AttachmentInstrumentationTest { + + @Test + public void testParcelableImplementation() { + Uri uri = Uri.parse("content://test/uri"); + String mimeType = "image/png"; + Attachment attachment = new Attachment(uri, mimeType); + + Parcel parcel = Parcel.obtain(); + attachment.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + Attachment createdFromParcel = Attachment.CREATOR.createFromParcel(parcel); + assertNotNull(createdFromParcel); + assertEquals(attachment.getId(), createdFromParcel.getId()); + assertEquals(attachment.getUri(), createdFromParcel.getUri()); + assertEquals(attachment.getMime_type(), createdFromParcel.getMime_type()); + } + + @Test + public void testConstructorWithBaseAttachment() { + Uri uri = Uri.parse("content://test/uri"); + String mimeType = "image/png"; + BaseAttachment baseAttachment = new BaseAttachment(1L, uri.toString(), "Test", 1024L, 0L, mimeType); + Attachment attachment = new Attachment(baseAttachment); + + assertNotNull(attachment); + assertEquals(baseAttachment.getId(), attachment.getId()); + assertEquals(baseAttachment.getUriPath(), attachment.getUri().toString()); + assertEquals(baseAttachment.getMime_type(), attachment.getMime_type()); + } +} \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/AlphaManagerInstrumentedTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/AlphaManagerInstrumentedTest.java new file mode 100644 index 000000000..265031058 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/AlphaManagerInstrumentedTest.java @@ -0,0 +1,39 @@ +package it.feio.android.omninotes.utils; + +import android.content.Context; +import android.view.View; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.junit.Assert.*; + +@RunWith(AndroidJUnit4.class) +public class AlphaManagerInstrumentedTest { + + private Context context; + private View testView; + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + testView = new View(context); + } + + @Test + public void testSetAlpha_validAlpha() { + float alphaValue = 0.5f; + AlphaManager.setAlpha(testView, alphaValue); + assertEquals("Alpha value should be set to 0.5", alphaValue, testView.getAlpha(), 0.0f); + } + + @Test + public void testSetAlpha_nullView() { + try { + AlphaManager.setAlpha(null, 0.5f); + } catch (Exception e) { + fail("Setting alpha on a null view should not throw an exception"); + } + } +} \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/AnimationsHelperInstrumentalTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/AnimationsHelperInstrumentalTest.java new file mode 100644 index 000000000..dec1597f2 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/AnimationsHelperInstrumentalTest.java @@ -0,0 +1,53 @@ +package it.feio.android.omninotes.utils; + +import android.animation.AnimatorListenerAdapter; +import android.content.Context; +import android.view.View; +import android.widget.ImageView; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.junit.Assert.*; + +@RunWith(AndroidJUnit4.class) +public class AnimationsHelperInstrumentalTest { + + private Context context; + private View view; + private ImageView expandedImageView; + private View targetView; + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + view = new View(context); + expandedImageView = new ImageView(context); + targetView = new View(context); + } + + @Test + public void testExpandOrCollapse_expand() { + // Initially set the view to GONE + view.setVisibility(View.GONE); + + // Call the method to expand + AnimationsHelper.expandOrCollapse(view, true); + + // Verify the view is visible after animation + assertEquals(View.VISIBLE, view.getVisibility()); + } + + @Test + public void testExpandOrCollapse_collapse() { + // Initially set the view to VISIBLE + view.setVisibility(View.GONE); + + // Call the method to collapse + AnimationsHelper.expandOrCollapse(view, false); + + // Verify the view is gone after animation + assertEquals(View.GONE, view.getVisibility()); + } +} \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/AssetUtilsInstrumentedTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/AssetUtilsInstrumentedTest.java new file mode 100644 index 000000000..3fcacdf20 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/AssetUtilsInstrumentedTest.java @@ -0,0 +1,36 @@ +package it.feio.android.omninotes.utils; + + import android.content.Context; + import android.content.res.AssetManager; + import androidx.test.core.app.ApplicationProvider; + import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; + import org.junit.Test; + import org.junit.runner.RunWith; + import static org.junit.Assert.*; + + @RunWith(AndroidJUnit4.class) + public class AssetUtilsInstrumentedTest { + + private Context context; + private AssetManager assetManager; + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + assetManager = context.getAssets(); + } + + @Test + public void testExists_invalidFile() throws Exception { + boolean exists = AssetUtils.exists("invalid_file.txt", "path/to/assets", assetManager); + assertFalse("File should not exist in the specified path", exists); + } + + @Test + public void testList_invalidPath() throws Exception { + String[] files = AssetUtils.list("invalid/path", assetManager); + assertNotNull("File list should not be null for an invalid path", files); + assertEquals("File list should be empty for an invalid path", 0, files.length); + } + } \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/ColorsUtilInstrumentalTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/ColorsUtilInstrumentalTest.java new file mode 100644 index 000000000..631432dc6 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/ColorsUtilInstrumentalTest.java @@ -0,0 +1,39 @@ +package it.feio.android.omninotes.utils; + +import android.graphics.Color; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.junit.Assert.*; + +@RunWith(AndroidJUnit4.class) +public class ColorsUtilInstrumentalTest { + + @Test + public void testCalculateColorLuminance_black() { + int black = Color.BLACK; + double luminance = ColorsUtil.calculateColorLuminance(black); + assertEquals("Luminance of black should be 0", 0.0, luminance, 0.01); + } + + @Test + public void testCalculateColorLuminance_white() { + int white = Color.WHITE; + double luminance = ColorsUtil.calculateColorLuminance(white); + assertEquals("Luminance of white should be 255", 255.0, luminance, 0.01); + } + + @Test + public void testGetContrastedColor_darkColor() { + int darkColor = Color.BLACK; + int contrastedColor = ColorsUtil.getContrastedColor(darkColor); + assertEquals("Contrasted color for dark color should be light", 1, contrastedColor); + } + + @Test + public void testGetContrastedColor_lightColor() { + int lightColor = Color.WHITE; + int contrastedColor = ColorsUtil.getContrastedColor(lightColor); + assertEquals("Contrasted color for light color should be dark", 0, contrastedColor); + } +} \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/DisplayInstrumentedTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/DisplayInstrumentedTest.java new file mode 100644 index 000000000..5a8e1b6dd --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/DisplayInstrumentedTest.java @@ -0,0 +1,106 @@ +package it.feio.android.omninotes.utils; + +import android.content.Context; +import android.graphics.Point; +import android.view.View; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.core.app.ActivityScenario; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import it.feio.android.omninotes.MainActivity; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.junit.Assert.*; + +@RunWith(AndroidJUnit4.class) +public class DisplayInstrumentedTest { + + private Context context; + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + } + + @Test + public void testGetRootView() { + try (ActivityScenario scenario = ActivityScenario.launch(MainActivity.class)) { + scenario.onActivity(activity -> { + View rootView = Display.getRootView(activity); + assertNotNull("Root view should not be null", rootView); + }); + } + } + + @Test + public void testGetUsableSize() { + Point size = Display.getUsableSize(context); + assertTrue("Usable width should be greater than 0", size.x > 0); + assertTrue("Usable height should be greater than 0", size.y > 0); + } + + @Test + public void testGetVisibleSize() { + try (ActivityScenario scenario = ActivityScenario.launch(MainActivity.class)) { + scenario.onActivity(activity -> { + Point size = Display.getVisibleSize(activity); + assertTrue("Visible width should be greater than 0", size.x > 0); + assertTrue("Visible height should be greater than 0", size.y > 0); + }); + } + } + + @Test + public void testGetFullSize() { + try (ActivityScenario scenario = ActivityScenario.launch(MainActivity.class)) { + scenario.onActivity(activity -> { + View rootView = Display.getRootView(activity); + Point size = Display.getFullSize(rootView); + assertTrue("Full width should be greater than 0", size.x > 0); + assertTrue("Full height should be greater than 0", size.y > 0); + }); + } + } + + @Test + public void testGetStatusBarHeight() { + int height = Display.getStatusBarHeight(context); + assertTrue("Status bar height should be greater than 0", height > 0); + } + + @Test + public void testGetNavigationBarHeightStandard() { + int height = Display.getNavigationBarHeightStandard(context); + assertTrue("Navigation bar height should be greater than or equal to 0", height >= 0); + } + + @Test + public void testGetScreenDimensions() { + Point size = Display.getScreenDimensions(context); + assertTrue("Screen width should be greater than 0", size.x > 0); + assertTrue("Screen height should be greater than 0", size.y > 0); + } + + @Test + public void testGetNavigationBarHeightKitkat() { + int height = Display.getNavigationBarHeightKitkat(context); + assertTrue("Navigation bar height should be greater than or equal to 0", height >= 0); + } + + @Test + public void testOrientationLandscape() { + boolean isLandscape = Display.orientationLandscape(context); + // Assuming the test device is in portrait mode + assertFalse("Orientation should not be landscape", isLandscape); + } + + @Test + public void testGetSoftButtonsBarHeight() { + try (ActivityScenario scenario = ActivityScenario.launch(MainActivity.class)) { + scenario.onActivity(activity -> { + int height = Display.getSoftButtonsBarHeight(activity); + assertTrue("Soft buttons bar height should be greater than or equal to 0", height >= 0); + }); + } + } +} diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/NavigationInstrumentedTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/NavigationInstrumentedTest.java new file mode 100644 index 000000000..1f446de88 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/NavigationInstrumentedTest.java @@ -0,0 +1,74 @@ +package it.feio.android.omninotes.utils; + +import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.pixplicity.easyprefs.library.Prefs; +import it.feio.android.omninotes.models.Category; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.junit.Assert.*; + +@RunWith(AndroidJUnit4.class) +public class NavigationInstrumentedTest { + + private Context context; + private String[] navigationListCodes; + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + Prefs.Builder prefsBuilder = new Prefs.Builder() + .setContext(context) + .setMode(Context.MODE_PRIVATE) + .setPrefsName(context.getPackageName()) + .setUseDefaultSharedPreference(true); + prefsBuilder.build(); + + // Simulate the values from R.array.navigation_list_codes + navigationListCodes = new String[]{"notes", "archive", "reminders", "trash", "uncategorized", "category"}; + } + + @Test + public void testGetNavigation() { + Prefs.putString(ConstantsBase.PREF_NAVIGATION, navigationListCodes[Navigation.NOTES]); + assertEquals(5, Navigation.getNavigation()); + + Prefs.putString(ConstantsBase.PREF_NAVIGATION, navigationListCodes[Navigation.ARCHIVE]); + assertEquals(5, Navigation.getNavigation()); + } + + @Test + public void testGetNavigationText() { + Prefs.putString(ConstantsBase.PREF_NAVIGATION, navigationListCodes[Navigation.REMINDERS]); + assertEquals(navigationListCodes[Navigation.REMINDERS], Navigation.getNavigationText()); + } + + @Test + public void testGetCategory() { + Prefs.putString(ConstantsBase.PREF_NAVIGATION, "1"); + assertEquals(Long.valueOf(1), Navigation.getCategory()); + + // Verify handling of non-numeric values + Prefs.putString(ConstantsBase.PREF_NAVIGATION, "not_a_category"); + try { + Navigation.getCategory(); + fail("Expected NumberFormatException"); + } catch (NumberFormatException e) { + // Expected exception + assertEquals("For input string: \"not_a_category\"", e.getMessage()); + } + } + + @Test + public void testCheckNavigationCategory() { + Category category = new Category(); + category.setId(1L); + Prefs.putString(ConstantsBase.PREF_NAVIGATION, "1"); + assertTrue("Expected category navigation to match", Navigation.checkNavigationCategory(category)); + + category.setId(2L); + assertFalse("Expected category navigation not to match", Navigation.checkNavigationCategory(category)); + } +} diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/ResourcesUtilsInstrumentalTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/ResourcesUtilsInstrumentalTest.java new file mode 100644 index 000000000..29b830886 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/ResourcesUtilsInstrumentalTest.java @@ -0,0 +1,56 @@ +package it.feio.android.omninotes.utils; + +import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.junit.Assert.*; + +@RunWith(AndroidJUnit4.class) +public class ResourcesUtilsInstrumentalTest { + + private Context context; + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + } + + @Test + public void testGetXmlId_validResource() { + int resourceId = ResourcesUtils.getXmlId(context, ResourcesUtils.ResourceIdentifiers.XML, "settings"); + assertTrue("Resource ID should not be 0 for valid XML resource", resourceId != 0); + } + + @Test + public void testGetXmlId_invalidResource() { + int resourceId = ResourcesUtils.getXmlId(context, ResourcesUtils.ResourceIdentifiers.XML, "invalid_resource_name"); + assertEquals("Resource ID should be 0 for invalid XML resource", 0, resourceId); + } + + @Test + public void testGetXmlId_validIdResource() { + int resourceId = ResourcesUtils.getXmlId(context, ResourcesUtils.ResourceIdentifiers.ID, "drawer_layout"); + assertTrue("Resource ID should not be 0 for valid ID resource", resourceId != 0); + } + + @Test + public void testGetXmlId_invalidIdResource() { + int resourceId = ResourcesUtils.getXmlId(context, ResourcesUtils.ResourceIdentifiers.ID, "invalid_id_name"); + assertEquals("Resource ID should be 0 for invalid ID resource", 0, resourceId); + } + + @Test + public void testGetXmlId_validArrayResource() { + int resourceId = ResourcesUtils.getXmlId(context, ResourcesUtils.ResourceIdentifiers.ARRAY, "navigation_list"); + assertTrue("Resource ID should not be 0 for valid array resource", resourceId != 0); + } + + @Test + public void testGetXmlId_invalidArrayResource() { + int resourceId = ResourcesUtils.getXmlId(context, ResourcesUtils.ResourceIdentifiers.ARRAY, "invalid_array_name"); + assertEquals("Resource ID should be 0 for invalid array resource", 0, resourceId); + } +} diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/SystemHelperTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/SystemHelperTest.java new file mode 100644 index 000000000..a3baa6494 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/SystemHelperTest.java @@ -0,0 +1,92 @@ +package it.feio.android.omninotes.utils; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import android.content.ClipboardManager; +import android.content.Context; +import android.content.ClipData; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import java.io.Closeable; +import java.io.IOException; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import it.feio.android.omninotes.utils.SystemHelper; + +@RunWith(AndroidJUnit4.class) +public class SystemHelperTest { + + @Mock + private Context contextMock; + + @Mock + private ClipboardManager clipboardManagerMock; + + @Before + public void setUp() { + MockitoAnnotations.openMocks(this); + when(contextMock.getSystemService(Context.CLIPBOARD_SERVICE)).thenReturn(clipboardManagerMock); + } + + @Test + public void testCloseCloseable() throws IOException { + Closeable closeableMock = mock(Closeable.class); + SystemHelper.closeCloseable(closeableMock); + verify(closeableMock, times(1)).close(); + + // Test with null closeable + SystemHelper.closeCloseable((Closeable) null); + } + + @Test + public void testCloseCloseableWithException() throws IOException { + Closeable closeableMock = mock(Closeable.class); + IOException testException = new IOException("Test exception"); + doThrow(testException).when(closeableMock).close(); + + // Should not throw exception + SystemHelper.closeCloseable(closeableMock); + verify(closeableMock, times(1)).close(); + + // Try with array of closeables + Closeable[] closeables = new Closeable[]{closeableMock}; + SystemHelper.closeCloseable(closeables); + // Should be called twice total (once from above, once from array) + verify(closeableMock, times(2)).close(); + } + + @Test + public void testCopyToClipboard() { + String text = "Sample text"; + SystemHelper.copyToClipboard(contextMock, text); + + // Using argument captor to verify the ClipData content + ArgumentCaptor clipDataCaptor = ArgumentCaptor.forClass(ClipData.class); + verify(clipboardManagerMock, times(1)).setPrimaryClip(clipDataCaptor.capture()); + + ClipData capturedClipData = clipDataCaptor.getValue(); + assertEquals("text label", capturedClipData.getDescription().getLabel()); + assertEquals(text, capturedClipData.getItemAt(0).getText()); + assertEquals(1, capturedClipData.getItemCount()); + assertNotNull(capturedClipData.getItemAt(0)); + } + + @Test + public void testCopyToClipboardWithEmptyText() { + String text = ""; + SystemHelper.copyToClipboard(contextMock, text); + + // Should still copy empty text + ArgumentCaptor clipDataCaptor = ArgumentCaptor.forClass(ClipData.class); + verify(clipboardManagerMock, times(1)).setPrimaryClip(clipDataCaptor.capture()); + + ClipData capturedClipData = clipDataCaptor.getValue(); + assertEquals("text label", capturedClipData.getDescription().getLabel()); + assertEquals("", capturedClipData.getItemAt(0).getText().toString()); + } +} diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/TagsHelperInstrumentationTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/TagsHelperInstrumentationTest.java new file mode 100644 index 000000000..c8ed2e6b1 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/TagsHelperInstrumentationTest.java @@ -0,0 +1,83 @@ +package it.feio.android.omninotes.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.content.Context; + +import androidx.core.util.Pair; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import it.feio.android.omninotes.models.Note; +import it.feio.android.omninotes.models.Tag; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class TagsHelperInstrumentationTest { + + private Context context; + private Note note; + private List tags; + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + note = new Note(); + tags = new ArrayList<>(); + tags.add(new Tag("#test", 1)); + tags.add(new Tag("#android", 1)); + tags.add(new Tag("#instrumentation", 1)); + } + + @Test + public void testRetrieveTags() { + note.setContent("#test #android #instrumentation"); + Map retrievedTags = TagsHelper.retrieveTags(note); + assertEquals(3, retrievedTags.size()); + assertTrue(retrievedTags.containsKey("#test")); + assertTrue(retrievedTags.containsKey("#android")); + assertTrue(retrievedTags.containsKey("#instrumentation")); + } + + @Test + public void testAddTagToNote() { + Integer[] selectedTags = {0, 1}; + Pair> result = TagsHelper.addTagToNote(tags, selectedTags, note); + assertTrue(result.first.contains("#test")); + assertTrue(result.first.contains("#android")); + assertFalse(result.first.contains("#instrumentation")); + } + + @Test + public void testRemoveTags() { + note.setContent("#test #android #instrumentation"); + String result = TagsHelper.removeTags(note.getContent(), Arrays.asList(tags.get(0), tags.get(1))); + assertFalse(result.contains("#test")); + assertFalse(result.contains("#android")); + assertTrue(result.contains("#instrumentation")); + } + + @Test + public void testGetTagsArray() { + String[] tagsArray = TagsHelper.getTagsArray(tags); + assertEquals("test (1)", tagsArray[0]); + assertEquals("android (1)", tagsArray[1]); + assertEquals("instrumentation (1)", tagsArray[2]); + } + + @Test + public void testGetPreselectedTagsArray() { + note.setContent("#test #android"); + Integer[] preselectedTags = TagsHelper.getPreselectedTagsArray(note, tags); + assertEquals(2, preselectedTags.length); + assertTrue(Arrays.asList(preselectedTags).contains(0)); + assertTrue(Arrays.asList(preselectedTags).contains(1)); + } +} \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/TextHelperInstrumentalTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/TextHelperInstrumentalTest.java new file mode 100644 index 000000000..8d96638ce --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/TextHelperInstrumentalTest.java @@ -0,0 +1,77 @@ +package it.feio.android.omninotes.utils; + +import android.content.Context; +import android.text.Spanned; +import android.text.SpannedString; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.pixplicity.easyprefs.library.Prefs; +import it.feio.android.omninotes.models.Note; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +@RunWith(AndroidJUnit4.class) +public class TextHelperInstrumentalTest { + + private Context context; + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + // Initialize Prefs with the correct context + Prefs.Builder builder = new Prefs.Builder(); + builder.setContext(context).build(); + } + + @Test + public void testParseTitleAndContent() { + Note note = new Note(); + note.setTitle("Test Title"); + note.setContent("Test Content"); + note.setLocked(false); + note.setChecklist(false); + + Spanned[] result = TextHelper.parseTitleAndContent(context, note); + assertEquals("Test Title", result[0].toString()); + assertEquals("Test Content", result[1].toString()); + } + + @Test + public void testCapitalize() { + String input = "test"; + String expected = "Test"; + assertEquals(expected, TextHelper.capitalize(input)); + } + + @Test + public void testCheckIntentCategory() { + String sqlCondition = "category_id = 5"; + assertEquals("5", TextHelper.checkIntentCategory(sqlCondition)); + } + + @Test + public void testGetDateText() { + Note note = new Note(); + note.setCreation(System.currentTimeMillis()); + note.setLastModification(System.currentTimeMillis()); + + String dateText = TextHelper.getDateText(context, note, 0); + assertNotNull(dateText); + } + + @Test + public void testGetAlternativeTitle() { + Note note = new Note(); + note.setCreation(System.currentTimeMillis()); + + Spanned spanned = new SpannedString(""); // Correct declaration of SpannedString + String alternativeTitle = TextHelper.getAlternativeTitle(context, note, spanned); + assertNotNull(alternativeTitle); + } +} \ No newline at end of file diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/date/RecurrenceHelperTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/date/RecurrenceHelperTest.java index aa4cc8cad..ba51010a0 100644 --- a/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/date/RecurrenceHelperTest.java +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/utils/date/RecurrenceHelperTest.java @@ -25,6 +25,11 @@ import org.junit.Test; import org.junit.runner.RunWith; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Locale; +import java.util.TimeZone; + @RunWith(AndroidJUnit4.class) public class RecurrenceHelperTest extends BaseAndroidTestCase { @@ -32,11 +37,25 @@ public class RecurrenceHelperTest extends BaseAndroidTestCase { public void getNoteRecurrentReminderText() { long reminder = 1577369824425L; String rrule = "FREQ=WEEKLY;WKST=MO;BYDAY=MO,TU,TH"; - String expectedRegex = "Weekly on Mon, Tue, Thu starting from Thu, Dec 26, 2019 [2|3]:17 PM"; + String alarmText = RecurrenceHelper.getNoteRecurrentReminderText(reminder, rrule); - String errorMsg = String.format("%s not matching %s", alarmText, expectedRegex); + alarmText = alarmText.replace("\u202F", " "); + String expectedText = getExpectedText(reminder); + String errorMsg = String.format("%s not matching %s", alarmText, expectedText); + + assertTrue(errorMsg, alarmText.matches(expectedText)); + } + + private String getExpectedText(long reminder) { + TimeZone localTimeZone = TimeZone.getDefault(); + Calendar calendar = Calendar.getInstance(localTimeZone); + calendar.setTimeInMillis(reminder); + + SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM dd, yyyy hh:mm a", Locale.getDefault()); + sdf.setTimeZone(localTimeZone); + String formattedDate = sdf.format(calendar.getTime()); - assertTrue(errorMsg, alarmText.matches(expectedRegex)); + return "Weekly on Mon, Tue, Thu starting from " + formattedDate; } } diff --git a/omniNotes/src/androidTest/java/it/feio/android/omninotes/widgets/ListRemoteViewsFactoryTest.java b/omniNotes/src/androidTest/java/it/feio/android/omninotes/widgets/ListRemoteViewsFactoryTest.java new file mode 100644 index 000000000..abcb08748 --- /dev/null +++ b/omniNotes/src/androidTest/java/it/feio/android/omninotes/widgets/ListRemoteViewsFactoryTest.java @@ -0,0 +1,87 @@ +package it.feio.android.omninotes.widgets; + +import android.app.Application; +import android.appwidget.AppWidgetManager; +import android.content.Context; +import android.content.Intent; +import android.widget.RemoteViews; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.rule.ActivityTestRule; + +import it.feio.android.omninotes.MainActivity; +import it.feio.android.omninotes.OmniNotes; +import it.feio.android.omninotes.widget.ListRemoteViewsFactory; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.junit.Assert.*; + +@RunWith(AndroidJUnit4.class) +public class ListRemoteViewsFactoryTest { + + private ListRemoteViewsFactory factory; + private Context context; + private int appWidgetId; + + @Rule + public ActivityTestRule activityRule = new ActivityTestRule<>(MainActivity.class); + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; + Intent intent = new Intent(); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + factory = new ListRemoteViewsFactory((Application) context, intent); + } + + @Test + public void testOnCreate() { + factory.onCreate(); + assertNotNull(factory); + assertTrue(factory.getCount() >= 0); + } + + @Test + public void testGetViewAt() { + factory.onCreate(); + if (factory.getCount() > 0) { + RemoteViews view = factory.getViewAt(0); + assertNotNull(view); + } + } + + @Test + public void testOnDataSetChanged() { + factory.onCreate(); + int initialCount = factory.getCount(); + factory.onDataSetChanged(); + assertEquals(initialCount, factory.getCount()); + } + + @Test + public void testGetLoadingView() { + assertNull(factory.getLoadingView()); + } + + @Test + public void testGetViewTypeCount() { + assertEquals(1, factory.getViewTypeCount()); + } + + @Test + public void testGetItemId() { + factory.onCreate(); + if (factory.getCount() > 0) { + assertEquals(0, factory.getItemId(0)); + } + } + + @Test + public void testHasStableIds() { + assertFalse(factory.hasStableIds()); + } +} \ No newline at end of file diff --git a/omniNotes/src/beta/java/it/feio/android/omninotes/utils/Constants.java b/omniNotes/src/beta/java/it/feio/android/omninotes/utils/Constants.java index 3dc7f8905..18a0b4c53 100644 --- a/omniNotes/src/beta/java/it/feio/android/omninotes/utils/Constants.java +++ b/omniNotes/src/beta/java/it/feio/android/omninotes/utils/Constants.java @@ -1,14 +1,16 @@ package it.feio.android.omninotes.utils; +public final class Constants extends ConstantsBase { -public interface Constants extends ConstantsBase { + public static final String TAG = "Omni Notes Beta"; + public static final String EXTERNAL_STORAGE_FOLDER = "Omni Notes"; + public static final String PACKAGE = "it.feio.android.omninotes"; - String TAG = "Omni Notes Beta"; - String EXTERNAL_STORAGE_FOLDER = "Omni Notes"; - String PACKAGE = "it.feio.android.omninotes"; + public static final String CHANNEL_BACKUPS_ID = PACKAGE + ".backups"; + public static final String CHANNEL_REMINDERS_ID = PACKAGE + ".reminders"; + public static final String CHANNEL_PINNED_ID = PACKAGE + ".pinned"; - String CHANNEL_BACKUPS_ID = PACKAGE + ".backups"; - String CHANNEL_REMINDERS_ID = PACKAGE + ".reminders"; - String CHANNEL_PINNED_ID = PACKAGE + ".pinned"; - -} + private Constants() { + throw new AssertionError("Cannot be instantiated"); + } +} \ No newline at end of file diff --git a/omniNotes/src/foss/java/it/feio/android/omninotes/utils/Constants.java b/omniNotes/src/foss/java/it/feio/android/omninotes/utils/Constants.java index 94669b711..789ea733d 100644 --- a/omniNotes/src/foss/java/it/feio/android/omninotes/utils/Constants.java +++ b/omniNotes/src/foss/java/it/feio/android/omninotes/utils/Constants.java @@ -16,14 +16,17 @@ */ package it.feio.android.omninotes.utils; -public interface Constants extends ConstantsBase { +public final class Constants extends ConstantsBase { - String TAG = "Omni Notes FOSS"; - String EXTERNAL_STORAGE_FOLDER = "Omni Notes Foss"; - String PACKAGE = "it.feio.android.omninotes.foss"; + public static final String TAG = "Omni Notes FOSS"; + public static final String EXTERNAL_STORAGE_FOLDER = "Omni Notes Foss"; + public static final String PACKAGE = "it.feio.android.omninotes.foss"; - String CHANNEL_BACKUPS_ID = PACKAGE + ".backups"; - String CHANNEL_REMINDERS_ID = PACKAGE + ".reminders"; - String CHANNEL_PINNED_ID = PACKAGE + ".pinned"; + public static final String CHANNEL_BACKUPS_ID = PACKAGE + ".backups"; + public static final String CHANNEL_REMINDERS_ID = PACKAGE + ".reminders"; + public static final String CHANNEL_PINNED_ID = PACKAGE + ".pinned"; -} + private Constants() { + throw new AssertionError("Cannot be instantiated"); + } +} \ No newline at end of file diff --git a/omniNotes/src/main/java/it/feio/android/omninotes/DetailFragment.java b/omniNotes/src/main/java/it/feio/android/omninotes/DetailFragment.java index f0270cfa3..65ea61a0c 100644 --- a/omniNotes/src/main/java/it/feio/android/omninotes/DetailFragment.java +++ b/omniNotes/src/main/java/it/feio/android/omninotes/DetailFragment.java @@ -466,104 +466,119 @@ private void checkNoteLock(Note note) { } private void handleIntents() { - Intent i = mainActivity.getIntent(); + Intent intent = mainActivity.getIntent(); - if (IntentChecker.checkAction(i, ACTION_MERGE)) { - noteOriginal = new Note(); - note = new Note(noteOriginal); - noteTmp = getArguments().getParcelable(INTENT_NOTE); - if (i.getStringArrayListExtra("merged_notes") != null) { - mergedNotesIds = i.getStringArrayListExtra("merged_notes"); - } + handleMergeIntent(intent); + handleShortcutIntent(intent); + handleWidgetIntents(intent); + handleFabTakePhoto(intent); + handleSendIntents(intent); + handleMainIntents(intent); + + intent.setAction(null); + } + + private void handleMergeIntent(Intent intent) { + if (!IntentChecker.checkAction(intent, ACTION_MERGE)) return; + + noteOriginal = new Note(); + note = new Note(noteOriginal); + noteTmp = getArguments().getParcelable(INTENT_NOTE); + if (intent.getStringArrayListExtra("merged_notes") != null) { + mergedNotesIds = intent.getStringArrayListExtra("merged_notes"); } + } - // Action called from home shortcut - if (IntentChecker.checkAction(i, ACTION_SHORTCUT, ACTION_NOTIFICATION_CLICK)) { - afterSavedReturnsToList = false; - noteOriginal = DbHelper.getInstance().getNote(i.getLongExtra(INTENT_KEY, 0)); - // Checks if the note pointed from the shortcut has been deleted - try { - note = new Note(noteOriginal); - noteTmp = new Note(noteOriginal); - } catch (NullPointerException e) { - mainActivity.showToast(getText(R.string.shortcut_note_deleted), Toast.LENGTH_LONG); - mainActivity.finish(); - } + private void handleShortcutIntent(Intent intent) { + if (!IntentChecker.checkAction(intent, ACTION_SHORTCUT, ACTION_NOTIFICATION_CLICK)) return; + + afterSavedReturnsToList = false; + noteOriginal = DbHelper.getInstance().getNote(intent.getLongExtra(INTENT_KEY, 0)); + + try { + note = new Note(noteOriginal); + noteTmp = new Note(noteOriginal); + } catch (NullPointerException e) { + mainActivity.showToast(getText(R.string.shortcut_note_deleted), Toast.LENGTH_LONG); + mainActivity.finish(); } + } - // Check if is launched from a widget - if (IntentChecker.checkAction(i, ACTION_WIDGET, ACTION_WIDGET_TAKE_PHOTO)) { + private void handleWidgetIntents(Intent intent) { + if (!IntentChecker.checkAction(intent, ACTION_WIDGET, ACTION_WIDGET_TAKE_PHOTO)) return; - afterSavedReturnsToList = false; - showKeyboard = true; + afterSavedReturnsToList = false; + showKeyboard = true; - // with tags to set tag - if (i.hasExtra(INTENT_WIDGET)) { - String widgetId = i.getExtras().get(INTENT_WIDGET).toString(); - String sqlCondition = Prefs.getString(PREF_WIDGET_PREFIX + widgetId, ""); - String categoryId = TextHelper.checkIntentCategory(sqlCondition); - if (categoryId != null) { - Category category; - try { - category = DbHelper.getInstance().getCategory(parseLong(categoryId)); - noteTmp = new Note(); - noteTmp.setCategory(category); - } catch (NumberFormatException e) { - LogDelegate.e("Category with not-numeric value!", e); - } - } - } + handleWidgetExtra(intent); + handleWidgetPhotoAction(intent); + } - // Sub-action is to take a photo - if (IntentChecker.checkAction(i, ACTION_WIDGET_TAKE_PHOTO)) { - takePhoto(); - } + private void handleWidgetExtra(Intent intent) { + if (!intent.hasExtra(INTENT_WIDGET)) return; + + String widgetId = intent.getExtras().get(INTENT_WIDGET).toString(); + String sqlCondition = Prefs.getString(PREF_WIDGET_PREFIX + widgetId, ""); + String categoryId = TextHelper.checkIntentCategory(sqlCondition); + + if (categoryId == null) return; + + try { + Category category = DbHelper.getInstance().getCategory(parseLong(categoryId)); + noteTmp = new Note(); + noteTmp.setCategory(category); + } catch (NumberFormatException e) { + LogDelegate.e("Category with not-numeric value!", e); } + } - if (IntentChecker.checkAction(i, ACTION_FAB_TAKE_PHOTO)) { + private void handleWidgetPhotoAction(Intent intent) { + if (IntentChecker.checkAction(intent, ACTION_WIDGET_TAKE_PHOTO)) { takePhoto(); } + } - // Handles third party apps requests of sharing - if (IntentChecker - .checkAction(i, Intent.ACTION_SEND, Intent.ACTION_SEND_MULTIPLE, Intent.ACTION_PROCESS_TEXT, INTENT_GOOGLE_NOW) - && i.getType() != null) { + private void handleFabTakePhoto(Intent intent) { + if (IntentChecker.checkAction(intent, ACTION_FAB_TAKE_PHOTO)) { + takePhoto(); + } + } - afterSavedReturnsToList = false; + private void handleSendIntents(Intent intent) { + if (!IntentChecker.checkAction(intent, Intent.ACTION_SEND, Intent.ACTION_SEND_MULTIPLE, + Intent.ACTION_PROCESS_TEXT, INTENT_GOOGLE_NOW) || intent.getType() == null) return; - if (noteTmp == null) { - noteTmp = new Note(); - } + afterSavedReturnsToList = false; + noteTmp = noteTmp != null ? noteTmp : new Note(); - // Text title - String title = i.getStringExtra(Intent.EXTRA_SUBJECT); - if (title != null) { - noteTmp.setTitle(title); - } - - // Text content - String content = null; - if (Intent.ACTION_PROCESS_TEXT.equals(i.getAction())){ - content = i.getStringExtra(Intent.EXTRA_PROCESS_TEXT).toString(); - } else { - content = i.getStringExtra(Intent.EXTRA_TEXT); - } + setNoteContentFromIntent(intent); + importAttachments(intent); + } - if (content != null) { - noteTmp.setContent(content); - } + private void setNoteContentFromIntent(Intent intent) { + String title = intent.getStringExtra(Intent.EXTRA_SUBJECT); + if (title != null) { + noteTmp.setTitle(title); + } - importAttachments(i); + String content = getContentFromIntent(intent); + if (content != null) { + noteTmp.setContent(content); + } + } + private String getContentFromIntent(Intent intent) { + if (Intent.ACTION_PROCESS_TEXT.equals(intent.getAction())) { + return intent.getStringExtra(Intent.EXTRA_PROCESS_TEXT); } + return intent.getStringExtra(Intent.EXTRA_TEXT); + } - if (IntentChecker - .checkAction(i, Intent.ACTION_MAIN, ACTION_WIDGET_SHOW_LIST, ACTION_SHORTCUT_WIDGET, - ACTION_WIDGET)) { + private void handleMainIntents(Intent intent) { + if (IntentChecker.checkAction(intent, Intent.ACTION_MAIN, ACTION_WIDGET_SHOW_LIST, + ACTION_SHORTCUT_WIDGET, ACTION_WIDGET)) { showKeyboard = true; } - - i.setAction(null); } private void importAttachments(Intent i) { diff --git a/omniNotes/src/main/java/it/feio/android/omninotes/ListFragment.java b/omniNotes/src/main/java/it/feio/android/omninotes/ListFragment.java index b66fc48bd..8022af0c9 100644 --- a/omniNotes/src/main/java/it/feio/android/omninotes/ListFragment.java +++ b/omniNotes/src/main/java/it/feio/android/omninotes/ListFragment.java @@ -1047,76 +1047,82 @@ void initNotesList(Intent intent) { binding.progressWheel.setAlpha(1); binding.list.setAlpha(0); - // Search for a tag - // A workaround to simplify it's to simulate normal search - if (Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getCategories() != null - && intent.getCategories().contains(Intent.CATEGORY_BROWSABLE)) { - searchTags = intent.getDataString().replace(UrlCompleter.HASHTAG_SCHEME, ""); - goBackOnToggleSearchLabel = true; + if (Intent.ACTION_VIEW.equals(intent.getAction()) { + handleTagSearch(intent); } if (ACTION_SHORTCUT_WIDGET.equals(intent.getAction())) { return; } - // Searching + handleSearchAndFilters(intent); + } + + private void handleTagSearch(Intent intent) { + if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_BROWSABLE)) { + searchTags = intent.getDataString().replace(UrlCompleter.HASHTAG_SCHEME, ""); + goBackOnToggleSearchLabel = true; + } + } + + private void handleSearchAndFilters(Intent intent) { searchQuery = searchQueryInstant; searchQueryInstant = null; - if (searchTags != null || searchQuery != null || searchUncompleteChecklists - || IntentChecker - .checkAction(intent, Intent.ACTION_SEARCH, ACTION_SEARCH_UNCOMPLETE_CHECKLISTS)) { - // Using tags - if (searchTags != null && intent.getStringExtra(SearchManager.QUERY) == null) { - searchQuery = searchTags; - NoteLoaderTask.getInstance() - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "getNotesByTag", - searchQuery); - } else if (searchUncompleteChecklists || ACTION_SEARCH_UNCOMPLETE_CHECKLISTS.equals( - intent.getAction())) { - searchQuery = getContext().getResources().getString(R.string.uncompleted_checklists); - searchUncompleteChecklists = true; - NoteLoaderTask.getInstance() - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "getNotesByUncompleteChecklist"); - } else { - // Get the intent, verify the action and get the query - if (intent.getStringExtra(SearchManager.QUERY) != null) { - searchQuery = intent.getStringExtra(SearchManager.QUERY); - searchTags = null; - } - NoteLoaderTask.getInstance() - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "getNotesByPattern", - searchQuery); - } + if (shouldPerformSearch(intent)) { + performSearch(intent); + } else { + loadNotesFromWidgetOrNavigation(intent); + } + } - toggleSearchLabel(true); + private boolean shouldPerformSearch(Intent intent) { + return searchTags != null || searchQuery != null || searchUncompleteChecklists + || IntentChecker.checkAction(intent, Intent.ACTION_SEARCH, ACTION_SEARCH_UNCOMPLETE_CHECKLISTS); + } + private void performSearch(Intent intent) { + if (searchTags != null && intent.getStringExtra(SearchManager.QUERY) == null) { + searchQuery = searchTags; + NoteLoaderTask.getInstance() + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "getNotesByTag", searchQuery); + } else if (searchUncompleteChecklists || ACTION_SEARCH_UNCOMPLETE_CHECKLISTS.equals(intent.getAction())) { + searchQuery = getContext().getResources().getString(R.string.uncompleted_checklists); + searchUncompleteChecklists = true; + NoteLoaderTask.getInstance() + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "getNotesByUncompleteChecklist"); } else { - // Check if is launched from a widget with categories - if ((ACTION_WIDGET_SHOW_LIST.equals(intent.getAction()) && intent.hasExtra(INTENT_WIDGET)) - || !isEmpty(mainActivity.navigationTmp)) { - String widgetId = - intent.hasExtra(INTENT_WIDGET) ? intent.getExtras().get(INTENT_WIDGET).toString() - : null; - if (widgetId != null) { - String sqlCondition = Prefs.getString(PREF_WIDGET_PREFIX + widgetId, ""); - String categoryId = TextHelper.checkIntentCategory(sqlCondition); - mainActivity.navigationTmp = !isEmpty(categoryId) ? categoryId : null; - } - intent.removeExtra(INTENT_WIDGET); - if (mainActivity.navigationTmp != null) { - Long categoryId = Long.parseLong(mainActivity.navigationTmp); - NoteLoaderTask.getInstance().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, - "getNotesByCategory", categoryId); - } else { - NoteLoaderTask.getInstance() - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "getAllNotes", true); - } + if (intent.getStringExtra(SearchManager.QUERY) != null) { + searchQuery = intent.getStringExtra(SearchManager.QUERY); + searchTags = null; + } + NoteLoaderTask.getInstance() + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "getNotesByPattern", searchQuery); + } + + toggleSearchLabel(true); + } + private void loadNotesFromWidgetOrNavigation(Intent intent) { + if ((ACTION_WIDGET_SHOW_LIST.equals(intent.getAction()) && intent.hasExtra(INTENT_WIDGET)) + || !isEmpty(mainActivity.navigationTmp)) { + String widgetId = intent.hasExtra(INTENT_WIDGET) ? intent.getExtras().get(INTENT_WIDGET).toString() : null; + if (widgetId != null) { + String sqlCondition = Prefs.getString(PREF_WIDGET_PREFIX + widgetId, ""); + String categoryId = TextHelper.checkIntentCategory(sqlCondition); + mainActivity.navigationTmp = !isEmpty(categoryId) ? categoryId : null; + } + intent.removeExtra(INTENT_WIDGET); + if (mainActivity.navigationTmp != null) { + Long categoryId = Long.parseLong(mainActivity.navigationTmp); + NoteLoaderTask.getInstance().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "getNotesByCategory", categoryId); } else { NoteLoaderTask.getInstance() - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "getAllNotes", true); + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "getAllNotes", true); } + } else { + NoteLoaderTask.getInstance() + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "getAllNotes", true); } } diff --git a/omniNotes/src/main/java/it/feio/android/omninotes/async/MainMenuTask.java b/omniNotes/src/main/java/it/feio/android/omninotes/async/MainMenuTask.java index 5953ad2fb..1bb7eaae2 100644 --- a/omniNotes/src/main/java/it/feio/android/omninotes/async/MainMenuTask.java +++ b/omniNotes/src/main/java/it/feio/android/omninotes/async/MainMenuTask.java @@ -140,6 +140,9 @@ private boolean checkSkippableItem(int i) { skippable = true; } break; + default: + skippable = false; + break; } return skippable; } diff --git a/omniNotes/src/main/java/it/feio/android/omninotes/db/DbHelper.java b/omniNotes/src/main/java/it/feio/android/omninotes/db/DbHelper.java index c0905a6a9..87534ced4 100644 --- a/omniNotes/src/main/java/it/feio/android/omninotes/db/DbHelper.java +++ b/omniNotes/src/main/java/it/feio/android/omninotes/db/DbHelper.java @@ -145,7 +145,7 @@ public static synchronized DbHelper getInstance(Context context) { public static synchronized DbHelper getInstance(boolean forcedNewInstance) { if (instance == null || forcedNewInstance) { Context context = (instance == null || instance.mContext == null) ? OmniNotes.getAppContext() - : instance.mContext; + : instance.mContext; instance = new DbHelper(context); } return instance; @@ -202,7 +202,7 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { for (String sqlFile : AssetUtils.list(SQL_DIR, mContext.getAssets())) { if (sqlFile.startsWith(UPGRADE_QUERY_PREFIX)) { int fileVersion = Integer.parseInt(sqlFile.substring(UPGRADE_QUERY_PREFIX.length(), - sqlFile.length() - UPGRADE_QUERY_SUFFIX.length())); + sqlFile.length() - UPGRADE_QUERY_SUFFIX.length())); if (fileVersion > oldVersion && fileVersion <= newVersion) { execSqlFile(sqlFile, db); } @@ -220,8 +220,8 @@ public Note updateNote(Note note, boolean updateLastModification) { db = getDatabase(true); String content = Boolean.TRUE.equals(note.isLocked()) - ? Security.encrypt(note.getContent(), Prefs.getString(PREF_PASSWORD, "")) - : note.getContent(); + ? Security.encrypt(note.getContent(), Prefs.getString(PREF_PASSWORD, "")) + : note.getContent(); // To ensure note and attachments insertions are atomic and boost performances transaction are used db.beginTransaction(); @@ -230,10 +230,10 @@ public Note updateNote(Note note, boolean updateLastModification) { values.put(KEY_TITLE, note.getTitle()); values.put(KEY_CONTENT, content); values.put(KEY_CREATION, - note.getCreation() != null ? note.getCreation() : Calendar.getInstance().getTimeInMillis()); + note.getCreation() != null ? note.getCreation() : Calendar.getInstance().getTimeInMillis()); long lastModification = note.getLastModification() != null && !updateLastModification - ? note.getLastModification() - : Calendar.getInstance().getTimeInMillis(); + ? note.getLastModification() + : Calendar.getInstance().getTimeInMillis(); values.put(KEY_LAST_MODIFICATION, lastModification); values.put(KEY_ARCHIVED, note.isArchived()); values.put(KEY_TRASHED, note.isTrashed()); @@ -254,13 +254,13 @@ public Note updateNote(Note note, boolean updateLastModification) { List deletedAttachments = note.getAttachmentsListOld(); for (Attachment attachment : note.getAttachmentsList()) { updateAttachment(note.get_id() != null ? note.get_id() : values.getAsLong(KEY_CREATION), - attachment, db); + attachment, db); deletedAttachments.remove(attachment); } // Remove from database deleted attachments for (Attachment attachmentDeleted : deletedAttachments) { db.delete(TABLE_ATTACHMENTS, KEY_ATTACHMENT_ID + " = ?", - new String[]{String.valueOf(attachmentDeleted.getId())}); + new String[]{String.valueOf(attachmentDeleted.getId())}); } db.setTransactionSuccessful(); @@ -268,7 +268,7 @@ public Note updateNote(Note note, boolean updateLastModification) { // Fill the note with correct data before returning it note.setCreation( - note.getCreation() != null ? note.getCreation() : values.getAsLong(KEY_CREATION)); + note.getCreation() != null ? note.getCreation() : values.getAsLong(KEY_CREATION)); note.setLastModification(values.getAsLong(KEY_LAST_MODIFICATION)); return note; @@ -278,7 +278,7 @@ public Note updateNote(Note note, boolean updateLastModification) { private void execSqlFile(String sqlFile, SQLiteDatabase db) throws SQLException, IOException { LogDelegate.i(" exec sql file: {}" + sqlFile); for (String sqlInstruction : SqlParser - .parseSqlFile(SQL_DIR + "/" + sqlFile, mContext.getAssets())) { + .parseSqlFile(SQL_DIR + "/" + sqlFile, mContext.getAssets())) { LogDelegate.v(" sql: {}" + sqlInstruction); try { db.execSQL(sqlInstruction); @@ -304,7 +304,7 @@ public Attachment updateAttachment(Attachment attachment) { public Attachment updateAttachment(long noteId, Attachment attachment, SQLiteDatabase db) { var valuesAttachments = new ContentValues(); valuesAttachments.put(KEY_ATTACHMENT_ID, - attachment.getId() != null ? attachment.getId() : Calendar.getInstance().getTimeInMillis()); + attachment.getId() != null ? attachment.getId() : Calendar.getInstance().getTimeInMillis()); valuesAttachments.put(KEY_ATTACHMENT_NOTE_ID, noteId); valuesAttachments.put(KEY_ATTACHMENT_URI, attachment.getUri().toString()); valuesAttachments.put(KEY_ATTACHMENT_MIME_TYPE, attachment.getMime_type()); @@ -361,7 +361,7 @@ public List getAllNotes(Boolean checkNavigation) { public List getNotesActive() { String whereCondition = - " WHERE " + KEY_ARCHIVED + " IS NOT 1 AND " + KEY_TRASHED + " IS NOT 1 "; + " WHERE " + KEY_ARCHIVED + " IS NOT 1 AND " + KEY_TRASHED + " IS NOT 1 "; return getNotes(whereCondition, true); } @@ -380,15 +380,15 @@ public List getNotesTrashed() { public List getNotesUncategorized() { String whereCondition = " WHERE " - + "(" + KEY_CATEGORY_ID + " IS NULL OR " + KEY_CATEGORY_ID + " == 0) " - + "AND " + KEY_TRASHED + " IS NOT 1"; + + "(" + KEY_CATEGORY_ID + " IS NULL OR " + KEY_CATEGORY_ID + " == 0) " + + "AND " + KEY_TRASHED + " IS NOT 1"; return getNotes(whereCondition, true); } public List getNotesWithLocation() { String whereCondition = " WHERE " + KEY_LONGITUDE + " IS NOT NULL " - + "AND " + KEY_LONGITUDE + " != 0 "; + + "AND " + KEY_LONGITUDE + " != 0 "; return getNotes(whereCondition, true); } @@ -410,7 +410,7 @@ public List getNotes(String whereCondition, boolean order) { } if (order) { sortOrder = - KEY_TITLE.equals(sortColumn) || KEY_REMINDER.equals(sortColumn) ? " ASC " : " DESC "; + KEY_TITLE.equals(sortColumn) || KEY_REMINDER.equals(sortColumn) ? " ASC " : " DESC "; } // In case of title sorting criteria it must be handled empty title by concatenating content @@ -418,32 +418,32 @@ public List getNotes(String whereCondition, boolean order) { // In case of reminder sorting criteria the empty reminder notes must be moved on bottom of results sortColumn = KEY_REMINDER.equals(sortColumn) ? "IFNULL(" + KEY_REMINDER + ", " + - "" + TIMESTAMP_UNIX_EPOCH + ")" : sortColumn; + "" + TIMESTAMP_UNIX_EPOCH + ")" : sortColumn; // Generic query to be specialized with conditions passed as parameter String query = "SELECT " - + KEY_CREATION + "," - + KEY_LAST_MODIFICATION + "," - + KEY_TITLE + "," - + KEY_CONTENT + "," - + KEY_ARCHIVED + "," - + KEY_TRASHED + "," - + KEY_REMINDER + "," - + KEY_REMINDER_FIRED + "," - + KEY_RECURRENCE_RULE + "," - + KEY_LATITUDE + "," - + KEY_LONGITUDE + "," - + KEY_ADDRESS + "," - + KEY_LOCKED + "," - + KEY_CHECKLIST + "," - + KEY_CATEGORY + "," - + KEY_CATEGORY_NAME + "," - + KEY_CATEGORY_DESCRIPTION + "," - + KEY_CATEGORY_COLOR - + " FROM " + TABLE_NOTES - + " LEFT JOIN " + TABLE_CATEGORY + " USING( " + KEY_CATEGORY + ") " - + whereCondition - + (order ? " ORDER BY " + sortColumn + " COLLATE NOCASE " + sortOrder : ""); + + KEY_CREATION + "," + + KEY_LAST_MODIFICATION + "," + + KEY_TITLE + "," + + KEY_CONTENT + "," + + KEY_ARCHIVED + "," + + KEY_TRASHED + "," + + KEY_REMINDER + "," + + KEY_REMINDER_FIRED + "," + + KEY_RECURRENCE_RULE + "," + + KEY_LATITUDE + "," + + KEY_LONGITUDE + "," + + KEY_ADDRESS + "," + + KEY_LOCKED + "," + + KEY_CHECKLIST + "," + + KEY_CATEGORY + "," + + KEY_CATEGORY_NAME + "," + + KEY_CATEGORY_DESCRIPTION + "," + + KEY_CATEGORY_COLOR + + " FROM " + TABLE_NOTES + + " LEFT JOIN " + TABLE_CATEGORY + " USING( " + KEY_CATEGORY + ") " + + whereCondition + + (order ? " ORDER BY " + sortColumn + " COLLATE NOCASE " + sortOrder : ""); LogDelegate.v("Query: " + query); @@ -471,14 +471,14 @@ public List getNotes(String whereCondition, boolean order) { // Eventual decryption of content if (Boolean.TRUE.equals(note.isLocked())) { note.setContent( - Security.decrypt(note.getContent(), Prefs.getString(PREF_PASSWORD, ""))); + Security.decrypt(note.getContent(), Prefs.getString(PREF_PASSWORD, ""))); } // Set category long categoryId = cursor.getLong(i++); if (categoryId != 0) { Category category = new Category(categoryId, cursor.getString(i++), - cursor.getString(i++), cursor.getString(i)); + cursor.getString(i++), cursor.getString(i)); note.setCategory(category); } @@ -540,7 +540,7 @@ public boolean deleteNote(long noteId, boolean keepAttachments) { db.delete(TABLE_NOTES, KEY_ID + " = ?", new String[]{String.valueOf(noteId)}); if (!keepAttachments) { db.delete(TABLE_ATTACHMENTS, KEY_ATTACHMENT_NOTE_ID + " = ?", - new String[]{String.valueOf(noteId)}); + new String[]{String.valueOf(noteId)}); } return true; } @@ -566,30 +566,30 @@ public List getNotesByPattern(String pattern) { String escapedPattern = escapeSql(pattern); int navigation = Navigation.getNavigation(); String whereCondition = " WHERE " - + KEY_TRASHED + (navigation == Navigation.TRASH ? " IS 1" : " IS NOT 1") - + (navigation == Navigation.ARCHIVE ? " AND " + KEY_ARCHIVED + " IS 1" : "") - + (navigation == Navigation.CATEGORY ? " AND " + KEY_CATEGORY + " = " + Navigation - .getCategory() : "") - + (navigation == Navigation.UNCATEGORIZED ? " AND (" + KEY_CATEGORY + " IS NULL OR " - + KEY_CATEGORY_ID - + " == 0) " : "") - + (checkNavigation(Navigation.REMINDERS) ? " AND " + KEY_REMINDER - + " IS NOT NULL" : "") - + " AND (" - + " ( " + KEY_LOCKED + " IS NOT 1 AND (" + KEY_TITLE + " LIKE '%" + escapedPattern - + "%' ESCAPE '\\' " + " OR " - + - KEY_CONTENT + " LIKE '%" + escapedPattern + "%' ESCAPE '\\' ))" - + " OR ( " + KEY_LOCKED + " = 1 AND " + KEY_TITLE + " LIKE '%" + escapedPattern - + "%' ESCAPE '\\' )" - + ")"; + + KEY_TRASHED + (navigation == Navigation.TRASH ? " IS 1" : " IS NOT 1") + + (navigation == Navigation.ARCHIVE ? " AND " + KEY_ARCHIVED + " IS 1" : "") + + (navigation == Navigation.CATEGORY ? " AND " + KEY_CATEGORY + " = " + Navigation + .getCategory() : "") + + (navigation == Navigation.UNCATEGORIZED ? " AND (" + KEY_CATEGORY + " IS NULL OR " + + KEY_CATEGORY_ID + + " == 0) " : "") + + (checkNavigation(Navigation.REMINDERS) ? " AND " + KEY_REMINDER + + " IS NOT NULL" : "") + + " AND (" + + " ( " + KEY_LOCKED + " IS NOT 1 AND (" + KEY_TITLE + " LIKE '%" + escapedPattern + + "%' ESCAPE '\\' " + " OR " + + + KEY_CONTENT + " LIKE '%" + escapedPattern + "%' ESCAPE '\\' ))" + + " OR ( " + KEY_LOCKED + " = 1 AND " + KEY_TITLE + " LIKE '%" + escapedPattern + + "%' ESCAPE '\\' )" + + ")"; return getNotes(whereCondition, true); } static String escapeSql(String pattern) { return StringUtils.replace(pattern, "'", "''") - .replace("%", "\\%") - .replace("_", "\\_"); + .replace("%", "\\%") + .replace("_", "\\_"); } @@ -601,9 +601,9 @@ static String escapeSql(String pattern) { */ public List getNotesWithReminder(boolean filterPastReminders) { String whereCondition = " WHERE " + KEY_REMINDER - + (filterPastReminders ? " >= " + Calendar.getInstance().getTimeInMillis() : " IS NOT NULL") - + " AND " + KEY_ARCHIVED + " IS NOT 1" - + " AND " + KEY_TRASHED + " IS NOT 1"; + + (filterPastReminders ? " >= " + Calendar.getInstance().getTimeInMillis() : " IS NOT NULL") + + " AND " + KEY_ARCHIVED + " IS NOT 1" + + " AND " + KEY_TRASHED + " IS NOT 1"; return getNotes(whereCondition, true); } @@ -615,9 +615,9 @@ public List getNotesWithReminder(boolean filterPastReminders) { */ public List getNotesWithReminderNotFired() { String whereCondition = " WHERE " + KEY_REMINDER + " IS NOT NULL" - + " AND " + KEY_REMINDER_FIRED + " IS NOT 1" - + " AND " + KEY_ARCHIVED + " IS NOT 1" - + " AND " + KEY_TRASHED + " IS NOT 1"; + + " AND " + KEY_REMINDER_FIRED + " IS NOT 1" + + " AND " + KEY_ARCHIVED + " IS NOT 1" + + " AND " + KEY_TRASHED + " IS NOT 1"; return getNotes(whereCondition, true); } @@ -638,8 +638,8 @@ public List getNotesWithLock(boolean locked) { */ public List getTodayReminders() { String whereCondition = - " WHERE DATE(" + KEY_REMINDER + "/1000, 'unixepoch') = DATE('now') AND " + - KEY_TRASHED + " IS NOT 1"; + " WHERE DATE(" + KEY_REMINDER + "/1000, 'unixepoch') = DATE('now') AND " + + KEY_TRASHED + " IS NOT 1"; return getNotes(whereCondition, false); } @@ -674,12 +674,12 @@ public List getMasked() { public List getNotesByCategory(Long categoryId) { List notes; boolean filterArchived = Prefs - .getBoolean(PREF_FILTER_ARCHIVED_IN_CATEGORIES + categoryId, false); + .getBoolean(PREF_FILTER_ARCHIVED_IN_CATEGORIES + categoryId, false); try { String whereCondition = " WHERE " - + KEY_CATEGORY_ID + " = " + categoryId - + " AND " + KEY_TRASHED + " IS NOT 1" - + (filterArchived ? " AND " + KEY_ARCHIVED + " IS NOT 1" : ""); + + KEY_CATEGORY_ID + " = " + categoryId + + " AND " + KEY_TRASHED + " IS NOT 1" + + (filterArchived ? " AND " + KEY_ARCHIVED + " IS NOT 1" : ""); notes = getNotes(whereCondition, true); } catch (NumberFormatException e) { notes = getAllNotes(true); @@ -704,10 +704,10 @@ public List getTags(Note note) { HashMap tagsMap = new HashMap<>(); String whereCondition = " WHERE " - + (note != null ? KEY_ID + " = " + note.get_id() + " AND " : "") - + "(" + KEY_CONTENT + " LIKE '%#%' OR " + KEY_TITLE + " LIKE '%#%' " + ")" - + " AND " + KEY_TRASHED + " IS " + (checkNavigation(Navigation.TRASH) ? "1" : " NOT 1") - + " AND " + KEY_LOCKED + " IS NOT 1"; + + (note != null ? KEY_ID + " = " + note.get_id() + " AND " : "") + + "(" + KEY_CONTENT + " LIKE '%#%' OR " + KEY_TITLE + " LIKE '%#%' " + ")" + + " AND " + KEY_TRASHED + " IS " + (checkNavigation(Navigation.TRASH) ? "1" : " NOT 1") + + " AND " + KEY_LOCKED + " IS NOT 1"; List notesRetrieved = getNotes(whereCondition, true); for (Note noteRetrieved : notesRetrieved) { @@ -733,8 +733,8 @@ public List getTags(Note note) { */ public List getNotesByTag(String tag) { return tag.contains(",") - ? getNotesByTag(tag.split(",")) - : getNotesByTag(new String[]{tag}); + ? getNotesByTag(tag.split(",")) + : getNotesByTag(new String[]{tag}); } @@ -749,23 +749,23 @@ public List getNotesByTag(String[] tags) { whereCondition.append(" AND "); } whereCondition.append(String.format("((%s IS 1 AND %s LIKE '%%%s%%') OR (%s is NOT 1 AND (%s LIKE '%%%s%%' OR %s LIKE '%%%s%%')))" - , KEY_LOCKED, KEY_TITLE, tags[i], KEY_LOCKED, KEY_CONTENT, tags[i], KEY_TITLE, tags[i])); + , KEY_LOCKED, KEY_TITLE, tags[i], KEY_LOCKED, KEY_CONTENT, tags[i], KEY_TITLE, tags[i])); } // Trashed notes must be included in search results only if search if performed from trash whereCondition.append(" AND " + KEY_TRASHED + " IS ") - .append(checkNavigation(Navigation.TRASH) ? "" : "NOT ").append("1"); + .append(checkNavigation(Navigation.TRASH) ? "" : "NOT ").append("1"); return getNotes(whereCondition.toString(), true).stream() - .map(note -> { - boolean matches = Arrays.stream(tags) - .allMatch(tag -> { - var p = Pattern.compile(".*(\\s|^)" + tag + "(\\s|$).*", MULTILINE); - return p.matcher((note.getTitle() + " " + note.getContent())).find(); - }); - return matches ? note : null; - }) - .filter(Objects::nonNull) - .collect(toList()); + .map(note -> { + boolean matches = Arrays.stream(tags) + .allMatch(tag -> { + var p = Pattern.compile(".*(\\s|^)" + tag + "(\\s|$).*", MULTILINE); + return p.matcher((note.getTitle() + " " + note.getContent())).find(); + }); + return matches ? note : null; + }) + .filter(Objects::nonNull) + .collect(toList()); } /** @@ -773,8 +773,8 @@ public List getNotesByTag(String[] tags) { */ public List getNotesByUncompleteChecklist() { String whereCondition = - " WHERE " + KEY_CHECKLIST + " = 1 AND " + KEY_CONTENT + " LIKE '%" + UNCHECKED_SYM + "%' AND " - + KEY_TRASHED + (checkNavigation(Navigation.TRASH) ? " IS 1" : " IS NOT 1"); + " WHERE " + KEY_CHECKLIST + " = 1 AND " + KEY_CONTENT + " LIKE '%" + UNCHECKED_SYM + "%' AND " + + KEY_TRASHED + (checkNavigation(Navigation.TRASH) ? " IS 1" : " IS NOT 1"); return getNotes(whereCondition, true); } @@ -795,15 +795,15 @@ public ArrayList getAllAttachments() { public ArrayList getAttachments(String whereCondition) { ArrayList attachmentsList = new ArrayList<>(); String sql = "SELECT " - + KEY_ATTACHMENT_ID + "," - + KEY_ATTACHMENT_URI + "," - + KEY_ATTACHMENT_NAME + "," - + KEY_ATTACHMENT_SIZE + "," - + KEY_ATTACHMENT_LENGTH + "," - + KEY_ATTACHMENT_MIME_TYPE + "," - + KEY_ATTACHMENT_NOTE_ID - + " FROM " + TABLE_ATTACHMENTS - + whereCondition; + + KEY_ATTACHMENT_ID + "," + + KEY_ATTACHMENT_URI + "," + + KEY_ATTACHMENT_NAME + "," + + KEY_ATTACHMENT_SIZE + "," + + KEY_ATTACHMENT_LENGTH + "," + + KEY_ATTACHMENT_MIME_TYPE + "," + + KEY_ATTACHMENT_NOTE_ID + + " FROM " + TABLE_ATTACHMENTS + + whereCondition; Cursor cursor = null; @@ -814,8 +814,8 @@ public ArrayList getAttachments(String whereCondition) { if (cursor.moveToFirst()) { do { var attachment = new Attachment(cursor.getLong(0), - Uri.parse(cursor.getString(1)), cursor.getString(2), cursor.getInt(3), - cursor.getInt(4), cursor.getString(5)); + Uri.parse(cursor.getString(1)), cursor.getString(2), cursor.getInt(3), + cursor.getInt(4), cursor.getString(5)); attachment.setNoteId(cursor.getLong(6)); attachmentsList.add(attachment); } while (cursor.moveToNext()); @@ -838,23 +838,23 @@ public ArrayList getAttachments(String whereCondition) { public ArrayList getCategories() { ArrayList categoriesList = new ArrayList<>(); String sql = "SELECT " - + KEY_CATEGORY_ID + "," - + KEY_CATEGORY_NAME + "," - + KEY_CATEGORY_DESCRIPTION + "," - + KEY_CATEGORY_COLOR + "," - + " COUNT(" + KEY_ID + ") count" - + " FROM " + TABLE_CATEGORY - + " LEFT JOIN (" - + " SELECT " + KEY_ID + ", " + KEY_CATEGORY - + " FROM " + TABLE_NOTES - + " WHERE " + KEY_TRASHED + " IS NOT 1" - + ") USING( " + KEY_CATEGORY + ") " - + " GROUP BY " - + KEY_CATEGORY_ID + "," - + KEY_CATEGORY_NAME + "," - + KEY_CATEGORY_DESCRIPTION + "," - + KEY_CATEGORY_COLOR - + " ORDER BY IFNULL(NULLIF(" + KEY_CATEGORY_NAME + ", ''),'zzzzzzzz') "; + + KEY_CATEGORY_ID + "," + + KEY_CATEGORY_NAME + "," + + KEY_CATEGORY_DESCRIPTION + "," + + KEY_CATEGORY_COLOR + "," + + " COUNT(" + KEY_ID + ") count" + + " FROM " + TABLE_CATEGORY + + " LEFT JOIN (" + + " SELECT " + KEY_ID + ", " + KEY_CATEGORY + + " FROM " + TABLE_NOTES + + " WHERE " + KEY_TRASHED + " IS NOT 1" + + ") USING( " + KEY_CATEGORY + ") " + + " GROUP BY " + + KEY_CATEGORY_ID + "," + + KEY_CATEGORY_NAME + "," + + KEY_CATEGORY_DESCRIPTION + "," + + KEY_CATEGORY_COLOR + + " ORDER BY IFNULL(NULLIF(" + KEY_CATEGORY_NAME + ", ''),'zzzzzzzz') "; Cursor cursor = null; try { @@ -863,8 +863,8 @@ public ArrayList getCategories() { if (cursor.moveToFirst()) { do { categoriesList.add(new Category(cursor.getLong(0), - cursor.getString(1), cursor.getString(2), cursor - .getString(3), cursor.getInt(4))); + cursor.getString(1), cursor.getString(2), cursor + .getString(3), cursor.getInt(4))); } while (cursor.moveToNext()); } @@ -886,7 +886,7 @@ public ArrayList getCategories() { public Category updateCategory(Category category) { ContentValues values = new ContentValues(); values.put(KEY_CATEGORY_ID, category.getId() != null ? category.getId() : Calendar.getInstance() - .getTimeInMillis()); + .getTimeInMillis()); values.put(KEY_CATEGORY_NAME, category.getName()); values.put(KEY_CATEGORY_DESCRIPTION, category.getDescription()); values.put(KEY_CATEGORY_COLOR, category.getColor()); @@ -911,11 +911,11 @@ public long deleteCategory(Category category) { // Updating row db.update(TABLE_NOTES, values, KEY_CATEGORY + " = ?", - new String[]{String.valueOf(category.getId())}); + new String[]{String.valueOf(category.getId())}); // Delete category deleted = db.delete(TABLE_CATEGORY, KEY_CATEGORY_ID + " = ?", - new String[]{String.valueOf(category.getId())}); + new String[]{String.valueOf(category.getId())}); return deleted; } @@ -926,18 +926,18 @@ public long deleteCategory(Category category) { public Category getCategory(Long id) { Category category = null; String sql = "SELECT " - + KEY_CATEGORY_ID + "," - + KEY_CATEGORY_NAME + "," - + KEY_CATEGORY_DESCRIPTION + "," - + KEY_CATEGORY_COLOR - + " FROM " + TABLE_CATEGORY - + " WHERE " + KEY_CATEGORY_ID + " = " + id; + + KEY_CATEGORY_ID + "," + + KEY_CATEGORY_NAME + "," + + KEY_CATEGORY_DESCRIPTION + "," + + KEY_CATEGORY_COLOR + + " FROM " + TABLE_CATEGORY + + " WHERE " + KEY_CATEGORY_ID + " = " + id; try (Cursor cursor = getDatabase().rawQuery(sql, null)) { if (cursor.moveToFirst()) { category = new Category(cursor.getLong(0), cursor.getString(1), - cursor.getString(2), cursor.getString(3)); + cursor.getString(2), cursor.getString(3)); } } @@ -948,8 +948,8 @@ public Category getCategory(Long id) { public int getCategorizedCount(Category category) { int count = 0; String sql = "SELECT COUNT(*)" - + " FROM " + TABLE_NOTES - + " WHERE " + KEY_CATEGORY + " = " + category.getId(); + + " FROM " + TABLE_NOTES + + " WHERE " + KEY_CATEGORY + " = " + category.getId(); try (Cursor cursor = getDatabase().rawQuery(sql, null)) { if (cursor.moveToFirst()) { @@ -969,7 +969,7 @@ public Stats getStats() { // Categories mStats.setCategories(getCategories().size()); - // Everything about notes and their text stats + // Initialize counters int notesActive = 0; int notesArchived = 0; int notesTrashed = 0; @@ -983,12 +983,10 @@ public Stats getStats() { int totalChars = 0; int maxWords = 0; int maxChars = 0; - int avgWords; - int avgChars; - int words; - int chars; + List notes = getAllNotes(false); for (Note note : notes) { + // Process note statistics if (Boolean.TRUE.equals(note.isTrashed())) { notesTrashed++; } else if (note.isArchived()) { @@ -996,6 +994,7 @@ public Stats getStats() { } else { notesActive++; } + if (note.getAlarm() != null && Long.parseLong(note.getAlarm()) > 0) { if (Long.parseLong(note.getAlarm()) > Calendar.getInstance().getTimeInMillis()) { remindersFuture++; @@ -1003,27 +1002,33 @@ public Stats getStats() { reminders++; } } + if (Boolean.TRUE.equals(note.isChecklist())) { checklists++; } + if (Boolean.TRUE.equals(note.isLocked())) { notesMasked++; } + tags += TagsHelper.retrieveTags(note).size(); + if (note.getLongitude() != null && note.getLongitude() != 0) { locations++; } - words = NotesHelper.getWords(note); - chars = NotesHelper.getChars(note); - if (words > maxWords) { - maxWords = words; - } - if (chars > maxChars) { - maxChars = chars; - } + + // Word and character statistics + int words = NotesHelper.getWords(note); + int chars = NotesHelper.getChars(note); + + maxWords = Math.max(maxWords, words); + maxChars = Math.max(maxChars, chars); + totalWords += words; totalChars += chars; } + + // Set statistics in Stats object mStats.setNotesActive(notesActive); mStats.setNotesArchived(notesArchived); mStats.setNotesTrashed(notesTrashed); @@ -1033,54 +1038,57 @@ public Stats getStats() { mStats.setNotesMasked(notesMasked); mStats.setTags(tags); mStats.setLocation(locations); - avgWords = totalWords / (!notes.isEmpty() ? notes.size() : 1); - avgChars = totalChars / (!notes.isEmpty() ? notes.size() : 1); + int noteCount = notes.size(); mStats.setWords(totalWords); mStats.setWordsMax(maxWords); - mStats.setWordsAvg(avgWords); + mStats.setWordsAvg(noteCount > 0 ? totalWords / noteCount : 0); mStats.setChars(totalChars); mStats.setCharsMax(maxChars); - mStats.setCharsAvg(avgChars); + mStats.setCharsAvg(noteCount > 0 ? totalChars / noteCount : 0); - // Everything about attachments - int images = 0; - int videos = 0; - int audioRecordings = 0; - int sketches = 0; - int files = 0; + // Process attachments + processAttachments(mStats); + return mStats; + } + + private void processAttachments(Stats mStats) { List attachments = getAllAttachments(); + + int images = 0, videos = 0, audioRecordings = 0, sketches = 0, files = 0; + for (Attachment attachment : attachments) { - if (MIME_TYPE_IMAGE.equals(attachment.getMime_type())) { - images++; - } else if (MIME_TYPE_VIDEO.equals(attachment.getMime_type())) { - videos++; - } else if (MIME_TYPE_AUDIO.equals(attachment.getMime_type())) { - audioRecordings++; - } else if (MIME_TYPE_SKETCH.equals(attachment.getMime_type())) { - sketches++; - } else if (MIME_TYPE_FILES.equals(attachment.getMime_type())) { - files++; + switch (attachment.getMime_type()) { + case MIME_TYPE_IMAGE: + images++; + break; + case MIME_TYPE_VIDEO: + videos++; + break; + case MIME_TYPE_AUDIO: + audioRecordings++; + break; + case MIME_TYPE_SKETCH: + sketches++; + break; + case MIME_TYPE_FILES: + files++; + break; } } + mStats.setAttachments(attachments.size()); mStats.setImages(images); mStats.setVideos(videos); mStats.setAudioRecordings(audioRecordings); mStats.setSketches(sketches); mStats.setFiles(files); - - return mStats; } - - public void setReminderFired(long noteId, boolean fired) { ContentValues values = new ContentValues(); values.put(KEY_REMINDER_FIRED, fired); getDatabase(true) - .update(TABLE_NOTES, values, KEY_ID + " = ?", new String[]{String.valueOf(noteId)}); + .update(TABLE_NOTES, values, KEY_ID + " = ?", new String[]{String.valueOf(noteId)}); } - - -} +} \ No newline at end of file diff --git a/omniNotes/src/main/java/it/feio/android/omninotes/db/SqlParser.java b/omniNotes/src/main/java/it/feio/android/omninotes/db/SqlParser.java index d7df58230..8443d567e 100644 --- a/omniNotes/src/main/java/it/feio/android/omninotes/db/SqlParser.java +++ b/omniNotes/src/main/java/it/feio/android/omninotes/db/SqlParser.java @@ -45,54 +45,50 @@ public static List parseSqlFile(InputStream is) throws IOException { return splitSqlScript(script, ';'); } - private static String removeComments(InputStream is) throws IOException { - - StringBuilder sql = new StringBuilder(); - - InputStreamReader isReader = new InputStreamReader(is); - try { - BufferedReader buffReader = new BufferedReader(isReader); - try { - String line; - String multiLineComment = null; - while ((line = buffReader.readLine()) != null) { - line = line.trim(); - - if (multiLineComment == null) { - if (line.startsWith("/*")) { - if (!line.endsWith("}")) { - multiLineComment = "/*"; + StringBuilder sql = new StringBuilder(); + try (BufferedReader buffReader = new BufferedReader(new InputStreamReader(is))) { + String line; + String multiLineComment = null; + + while ((line = buffReader.readLine()) != null) { + line = line.trim(); + + if (multiLineComment != null) { + multiLineComment = checkMultiLineCommentEnd(multiLineComment, line); + continue; + } + + if (isStartOfMultiLineComment(line)) { + multiLineComment = getMultiLineCommentStart(line); + continue; } - } else if (line.startsWith("{")) { - if (!line.endsWith("}")) { - multiLineComment = "{"; + + if (!isSingleLineComment(line) && !line.isEmpty()) { + sql.append(" ").append(line); } - } else if (!line.startsWith("--") && !line.equals("")) { - sql.append(" ").append(line); - } - } else if (multiLineComment.equals("/*")) { - if (line.endsWith("*/")) { - multiLineComment = null; - } - } else if (multiLineComment.equals("{")) { - if (line.endsWith("}")) { - multiLineComment = null; - } } - - } - } finally { - buffReader.close(); } + return sql.toString(); + } - } finally { - isReader.close(); - } + private static boolean isSingleLineComment(String line) { + return line.startsWith("--"); + } - return sql.toString(); + private static boolean isStartOfMultiLineComment(String line) { + return line.startsWith("/*") || line.startsWith("{"); } + private static String getMultiLineCommentStart(String line) { + return (!line.endsWith("}")) ? (line.startsWith("/*") ? "/*" : "{") : null; + } + + private static String checkMultiLineCommentEnd(String multiLineComment, String line) { + return (multiLineComment.equals("/*") && line.endsWith("*/")) || (multiLineComment.equals("{") && line.endsWith("}")) + ? null + : multiLineComment; + } private static List splitSqlScript(String script, char delim) { List statements = new ArrayList<>(); @@ -117,5 +113,4 @@ private static List splitSqlScript(String script, char delim) { } return statements; } - } diff --git a/omniNotes/src/main/java/it/feio/android/omninotes/helpers/SpringImportHelper.java b/omniNotes/src/main/java/it/feio/android/omninotes/helpers/SpringImportHelper.java index 409e0669c..7a6a5863e 100644 --- a/omniNotes/src/main/java/it/feio/android/omninotes/helpers/SpringImportHelper.java +++ b/omniNotes/src/main/java/it/feio/android/omninotes/helpers/SpringImportHelper.java @@ -52,6 +52,7 @@ public class SpringImportHelper { public static final String ACTION_DATA_IMPORT_SPRINGPAD = "action_data_import_springpad"; public static final String EXTRA_SPRINGPAD_BACKUP = "extra_springpad_backup"; private final Context context; + private static final String LINE_SEPARATOR = System.getProperty("line.separator"); private int importedSpringpadNotes, importedSpringpadNotebooks; @@ -64,22 +65,22 @@ public SpringImportHelper(Context context) { /** * Imports notes and notebooks from Springpad exported archive */ - public synchronized void importDataFromSpringpad(Intent intent, - NotificationsHelper mNotificationsHelper) { + public synchronized void importDataFromSpringpad(Intent intent, NotificationsHelper mNotificationsHelper) { + String backupPath = intent.getStringExtra(EXTRA_SPRINGPAD_BACKUP); Importer importer = new Importer(); try { importer.setZipProgressesListener(percentage -> mNotificationsHelper.setMessage(context - .getString(R.string.extracted) + " " + percentage + "%").show()); + .getString(R.string.extracted) + " " + percentage + "%").show()); importer.doImport(backupPath); // Updating notification updateImportNotification(importer, mNotificationsHelper); } catch (ImportException e) { new NotificationsHelper(context) - .createStandardNotification(NotificationChannelNames.BACKUPS, - R.drawable.ic_emoticon_sad_white_24dp, - context.getString(R.string.import_fail) + ": " + e.getMessage(), null).setLedActive() - .show(); + .createStandardNotification(NotificationChannelNames.BACKUPS, + R.drawable.ic_emoticon_sad_white_24dp, + context.getString(R.string.import_fail) + ": " + e.getMessage(), null).setLedActive() + .show(); return; } List elements = importer.getSpringpadNotes(); @@ -123,10 +124,10 @@ public synchronized void importDataFromSpringpad(Intent intent, // Content dependent from type of Springpad note StringBuilder content = new StringBuilder(); content.append( - TextUtils.isEmpty(springpadElement.getText()) ? "" : Html.fromHtml(springpadElement - .getText())); + TextUtils.isEmpty(springpadElement.getText()) ? "" : Html.fromHtml(springpadElement + .getText())); content.append(TextUtils.isEmpty(springpadElement.getDescription()) ? "" : springpadElement - .getDescription()); + .getDescription()); // Some notes could have been exported wrongly if (springpadElement.getType() == null) { @@ -136,56 +137,56 @@ public synchronized void importDataFromSpringpad(Intent intent, if (springpadElement.getType().equals(SpringpadElement.TYPE_VIDEO)) { try { - content.append(System.getProperty("line.separator")) - .append(springpadElement.getVideos().get(0)); + content.append(LINE_SEPARATOR) + .append(springpadElement.getVideos().get(0)); } catch (IndexOutOfBoundsException e) { - content.append(System.getProperty("line.separator")).append(springpadElement.getUrl()); + content.append(LINE_SEPARATOR).append(springpadElement.getUrl()); } } if (springpadElement.getType().equals(SpringpadElement.TYPE_TVSHOW)) { - content.append(System.getProperty("line.separator")).append( - TextUtils.join(", ", springpadElement.getCast())); + content.append(LINE_SEPARATOR).append( + TextUtils.join(", ", springpadElement.getCast())); } if (springpadElement.getType().equals(SpringpadElement.TYPE_BOOK)) { - content.append(System.getProperty("line.separator")).append("Author: ") - .append(springpadElement.getAuthor()).append(System.getProperty("line.separator")) - .append("Publication date: ").append(springpadElement.getPublicationDate()); + content.append(LINE_SEPARATOR).append("Author: ") + .append(springpadElement.getAuthor()).append(LINE_SEPARATOR) + .append("Publication date: ").append(springpadElement.getPublicationDate()); } if (springpadElement.getType().equals(SpringpadElement.TYPE_RECIPE)) { - content.append(System.getProperty("line.separator")).append("Ingredients: ") - .append(springpadElement.getIngredients()).append(System.getProperty("line.separator")) - .append("Directions: ").append(springpadElement.getDirections()); + content.append(LINE_SEPARATOR).append("Ingredients: ") + .append(springpadElement.getIngredients()).append(LINE_SEPARATOR) + .append("Directions: ").append(springpadElement.getDirections()); } if (springpadElement.getType().equals(SpringpadElement.TYPE_BOOKMARK)) { - content.append(System.getProperty("line.separator")).append(springpadElement.getUrl()); + content.append(LINE_SEPARATOR).append(springpadElement.getUrl()); } if (springpadElement.getType().equals(SpringpadElement.TYPE_BUSINESS) - && springpadElement.getPhoneNumbers() != null) { - content.append(System.getProperty("line.separator")).append("Phone number: ") - .append(springpadElement.getPhoneNumbers().getPhone()); + && springpadElement.getPhoneNumbers() != null) { + content.append(LINE_SEPARATOR).append("Phone number: ") + .append(springpadElement.getPhoneNumbers().getPhone()); } if (springpadElement.getType().equals(SpringpadElement.TYPE_PRODUCT)) { - content.append(System.getProperty("line.separator")).append("Category: ") - .append(springpadElement.getCategory()).append(System.getProperty("line.separator")) - .append("Manufacturer: ").append(springpadElement.getManufacturer()) - .append(System.getProperty("line.separator")).append("Price: ") - .append(springpadElement.getPrice()); + content.append(LINE_SEPARATOR).append("Category: ") + .append(springpadElement.getCategory()).append(LINE_SEPARATOR) + .append("Manufacturer: ").append(springpadElement.getManufacturer()) + .append(LINE_SEPARATOR).append("Price: ") + .append(springpadElement.getPrice()); } if (springpadElement.getType().equals(SpringpadElement.TYPE_WINE)) { - content.append(System.getProperty("line.separator")).append("Wine type: ") - .append(springpadElement.getWine_type()).append(System.getProperty("line.separator")) - .append("Varietal: ").append(springpadElement.getVarietal()) - .append(System.getProperty("line.separator")).append("Price: ") - .append(springpadElement.getPrice()); + content.append(LINE_SEPARATOR).append("Wine type: ") + .append(springpadElement.getWine_type()).append(LINE_SEPARATOR) + .append("Varietal: ").append(springpadElement.getVarietal()) + .append(LINE_SEPARATOR).append("Price: ") + .append(springpadElement.getPrice()); } if (springpadElement.getType().equals(SpringpadElement.TYPE_ALBUM)) { - content.append(System.getProperty("line.separator")).append("Artist: ") - .append(springpadElement.getArtist()); + content.append(LINE_SEPARATOR).append("Artist: ") + .append(springpadElement.getArtist()); } for (SpringpadComment springpadComment : springpadElement.getComments()) { - content.append(System.getProperty("line.separator")).append(springpadComment.getCommenter()) - .append(" commented at 0").append(springpadComment.getDate()).append(": ") - .append(springpadElement.getArtist()); + content.append(LINE_SEPARATOR).append(springpadComment.getCommenter()) + .append(" commented at 0").append(springpadComment.getDate()).append(": ") + .append(springpadElement.getArtist()); } note.setContent(content.toString()); @@ -196,11 +197,11 @@ public synchronized void importDataFromSpringpad(Intent intent, String checkmark; for (SpringpadItem mSpringpadItem : springpadElement.getItems()) { checkmark = - mSpringpadItem.getComplete() ? it.feio.android.checklistview.interfaces.Constants - .CHECKED_SYM - : it.feio.android.checklistview.interfaces.Constants.UNCHECKED_SYM; + mSpringpadItem.getComplete() ? it.feio.android.checklistview.interfaces.Constants + .CHECKED_SYM + : it.feio.android.checklistview.interfaces.Constants.UNCHECKED_SYM; sb.append(checkmark).append(mSpringpadItem.getName()) - .append(System.getProperty("line.separator")); + .append(LINE_SEPARATOR); } note.setContent(sb.toString()); note.setChecklist(true); @@ -208,17 +209,17 @@ public synchronized void importDataFromSpringpad(Intent intent, // Tags String tags = springpadElement.getTags().size() > 0 ? "#" - + TextUtils.join(" #", springpadElement.getTags()) : ""; + + TextUtils.join(" #", springpadElement.getTags()) : ""; if (note.isChecklist()) { note.setTitle(note.getTitle() + tags); } else { - note.setContent(note.getContent() + System.getProperty("line.separator") + tags); + note.setContent(note.getContent() + LINE_SEPARATOR + tags); } // Address String address = - springpadElement.getAddresses() != null ? springpadElement.getAddresses().getAddress() - : ""; + springpadElement.getAddresses() != null ? springpadElement.getAddresses().getAddress() + : ""; if (!TextUtils.isEmpty(address)) { try { double[] coords = GeocodeHelper.getCoordinatesFromAddress(context, address); @@ -226,7 +227,7 @@ public synchronized void importDataFromSpringpad(Intent intent, note.setLongitude(coords[1]); } catch (IOException e) { LogDelegate.e("An error occurred trying to resolve address to coords during Springpad " + - "import"); + "import"); } note.setAddress(address); } @@ -274,7 +275,7 @@ public synchronized void importDataFromSpringpad(Intent intent, // Tries first with online images try { File file = StorageHelper - .createNewAttachmentFileFromHttp(context, springpadAttachment.getUrl()); + .createNewAttachmentFileFromHttp(context, springpadAttachment.getUrl()); uri = Uri.fromFile(file); String mimeType = StorageHelper.getMimeType(uri.getPath()); mAttachment = new Attachment(uri, mimeType); @@ -316,11 +317,11 @@ public synchronized void importDataFromSpringpad(Intent intent, private void updateImportNotification(Importer importer, - NotificationsHelper mNotificationsHelper) { + NotificationsHelper mNotificationsHelper) { mNotificationsHelper.setMessage( - importer.getNotebooksCount() + " " + context.getString(R.string.categories) + " (" - + importedSpringpadNotebooks + " " + context.getString(R.string.imported) + "), " - + +importer.getNotesCount() + " " + context.getString(R.string.notes) + " (" - + importedSpringpadNotes + " " + context.getString(R.string.imported) + ")").show(); + importer.getNotebooksCount() + " " + context.getString(R.string.categories) + " (" + + importedSpringpadNotebooks + " " + context.getString(R.string.imported) + "), " + + +importer.getNotesCount() + " " + context.getString(R.string.notes) + " (" + + importedSpringpadNotes + " " + context.getString(R.string.imported) + ")").show(); } -} +} \ No newline at end of file diff --git a/omniNotes/src/main/java/it/feio/android/omninotes/models/views/VerticalSeekBar.java b/omniNotes/src/main/java/it/feio/android/omninotes/models/views/VerticalSeekBar.java index b7b86658c..2c65f8428 100644 --- a/omniNotes/src/main/java/it/feio/android/omninotes/models/views/VerticalSeekBar.java +++ b/omniNotes/src/main/java/it/feio/android/omninotes/models/views/VerticalSeekBar.java @@ -74,39 +74,41 @@ protected synchronized void onDraw(Canvas c) { @Override public boolean onTouchEvent(MotionEvent event) { - if (!isEnabled()) { - return false; - } - - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - setSelected(true); - setPressed(true); - if (changeListener != null) { - changeListener.onStartTrackingTouch(this); - } - break; - case MotionEvent.ACTION_UP: - setSelected(false); - setPressed(false); - if (changeListener != null) { - changeListener.onStopTrackingTouch(this); - } - break; - case MotionEvent.ACTION_MOVE: - int progress = getMax() - - (int) (getMax() * event.getY() / getHeight()); - setProgress(progress); - onSizeChanged(getWidth(), getHeight(), 0, 0); - if (changeListener != null) { - changeListener.onProgressChanged(this, progress, true); - } - break; - - case MotionEvent.ACTION_CANCEL: - break; - } - return true; + if (!isEnabled()) { + return false; + } + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + setSelected(true); + setPressed(true); + if (changeListener != null) { + changeListener.onStartTrackingTouch(this); + } + break; + case MotionEvent.ACTION_UP: + setSelected(false); + setPressed(false); + if (changeListener != null) { + changeListener.onStopTrackingTouch(this); + } + break; + case MotionEvent.ACTION_MOVE: + int progress = getMax() + - (int) (getMax() * event.getY() / getHeight()); + setProgress(progress); + onSizeChanged(getWidth(), getHeight(), 0, 0); + if (changeListener != null) { + changeListener.onProgressChanged(this, progress, true); + } + break; + case MotionEvent.ACTION_CANCEL: + break; + default: + // Handle any unrecognized events or do nothing + break; + } + return true; } diff --git a/omniNotes/src/main/java/it/feio/android/omninotes/utils/AssetUtils.java b/omniNotes/src/main/java/it/feio/android/omninotes/utils/AssetUtils.java index 6d53d86b6..281eea959 100644 --- a/omniNotes/src/main/java/it/feio/android/omninotes/utils/AssetUtils.java +++ b/omniNotes/src/main/java/it/feio/android/omninotes/utils/AssetUtils.java @@ -20,7 +20,6 @@ import java.io.IOException; import java.util.Arrays; - public class AssetUtils { private AssetUtils() { @@ -29,9 +28,16 @@ private AssetUtils() { public static boolean exists(String fileName, String path, AssetManager assetManager) throws IOException { - for (String currentFileName : assetManager.list(path)) { - if (currentFileName.equals(fileName)) { - return true; + if (fileName == null || path == null || assetManager == null) { + throw new IllegalArgumentException("Arguments cannot be null."); + } + + String[] fileList = assetManager.list(path); + if (fileList != null) { + for (String currentFileName : fileList) { + if (fileName.equals(currentFileName)) { + return true; + } } } return false; @@ -39,9 +45,15 @@ public static boolean exists(String fileName, String path, public static String[] list(String path, AssetManager assetManager) throws IOException { + if (path == null || assetManager == null) { + throw new IllegalArgumentException("Arguments cannot be null."); + } + String[] files = assetManager.list(path); + if (files == null) { + return new String[0]; // Retorna um array vazio se o diretório não existir ou estiver vazio + } Arrays.sort(files); return files; } - } diff --git a/omniNotes/src/main/java/it/feio/android/omninotes/utils/ConstantsBase.java b/omniNotes/src/main/java/it/feio/android/omninotes/utils/ConstantsBase.java index 4aee9f953..2b47a09ff 100644 --- a/omniNotes/src/main/java/it/feio/android/omninotes/utils/ConstantsBase.java +++ b/omniNotes/src/main/java/it/feio/android/omninotes/utils/ConstantsBase.java @@ -16,108 +16,106 @@ */ package it.feio.android.omninotes.utils; -public interface ConstantsBase { - - String DATABASE_NAME = "omni-notes"; - String APP_STORAGE_DIRECTORY_SB_SYNC = "db_sync"; - String COMMUNITY_LINK = "https://t.me/omninotes"; - - // Notes swipe - int SWIPE_MARGIN = 30; - int SWIPE_OFFSET = 100; - - // Floating action button - int FAB_ANIMATION_TIME = 250; - - // Notes content masking - String MASK_CHAR = "*"; - - int THUMBNAIL_SIZE = 300; - - String DATE_FORMAT_SORTABLE = "yyyyMMdd_HHmmss_SSS"; - String DATE_FORMAT_SORTABLE_OLD = "yyyyMMddHHmmss"; - String DATE_FORMAT_EXPORT = "yyyy.MM.dd-HH.mm"; - - String INTENT_KEY = "note_id"; - String INTENT_NOTE = "note"; - String GALLERY_TITLE = "gallery_title"; - String GALLERY_CLICKED_IMAGE = "gallery_clicked_image"; - String GALLERY_IMAGES = "gallery_images"; - String INTENT_CATEGORY = "category"; - String INTENT_GOOGLE_NOW = "com.google.android.gm.action.AUTO_SEND"; - String INTENT_WIDGET = "widget_id"; - String INTENT_UPDATE_DASHCLOCK = "update_dashclock"; - - // Custom intent actions - String ACTION_START_APP = "action_start_app"; - String ACTION_RESTART_APP = "action_restart_app"; - String ACTION_DISMISS = "action_dismiss"; - String ACTION_SNOOZE = "action_snooze"; - String ACTION_POSTPONE = "action_postpone"; - String ACTION_PINNED = "action_pinned"; - String ACTION_SHORTCUT = "action_shortcut"; - String ACTION_WIDGET = "action_widget"; - String ACTION_WIDGET_TAKE_PHOTO = "action_widget_take_photo"; - String ACTION_WIDGET_SHOW_LIST = "action_widget_show_list"; - String ACTION_SHORTCUT_WIDGET = "action_shortcut_widget"; - String ACTION_NOTIFICATION_CLICK = "action_notification_click"; - String ACTION_MERGE = "action_merge"; - String ACTION_FAB_TAKE_PHOTO = "action_fab_take_photo"; +public class ConstantsBase { + + public static final String DATABASE_NAME = "omni-notes"; + public static final String APP_STORAGE_DIRECTORY_SB_SYNC = "db_sync"; + public static final String COMMUNITY_LINK = "https://t.me/omninotes"; + + public static final int SWIPE_MARGIN = 30; + public static final int SWIPE_OFFSET = 100; + + public static final int FAB_ANIMATION_TIME = 250; + + public static final String MASK_CHAR = "*"; + + public static final int THUMBNAIL_SIZE = 300; + + public static final String DATE_FORMAT_SORTABLE = "yyyyMMdd_HHmmss_SSS"; + public static final String DATE_FORMAT_SORTABLE_OLD = "yyyyMMddHHmmss"; + public static final String DATE_FORMAT_EXPORT = "yyyy.MM.dd-HH.mm"; + + public static final String INTENT_KEY = "note_id"; + public static final String INTENT_NOTE = "note"; + public static final String GALLERY_TITLE = "gallery_title"; + public static final String GALLERY_CLICKED_IMAGE = "gallery_clicked_image"; + public static final String GALLERY_IMAGES = "gallery_images"; + public static final String INTENT_CATEGORY = "category"; + public static final String INTENT_GOOGLE_NOW = "com.google.android.gm.action.AUTO_SEND"; + public static final String INTENT_WIDGET = "widget_id"; + public static final String INTENT_UPDATE_DASHCLOCK = "update_dashclock"; + + public static final String ACTION_START_APP = "action_start_app"; + public static final String ACTION_RESTART_APP = "action_restart_app"; + public static final String ACTION_DISMISS = "action_dismiss"; + public static final String ACTION_SNOOZE = "action_snooze"; + public static final String ACTION_POSTPONE = "action_postpone"; + public static final String ACTION_PINNED = "action_pinned"; + public static final String ACTION_SHORTCUT = "action_shortcut"; + public static final String ACTION_WIDGET = "action_widget"; + public static final String ACTION_WIDGET_TAKE_PHOTO = "action_widget_take_photo"; + public static final String ACTION_WIDGET_SHOW_LIST = "action_widget_show_list"; + public static final String ACTION_SHORTCUT_WIDGET = "action_shortcut_widget"; + public static final String ACTION_NOTIFICATION_CLICK = "action_notification_click"; + public static final String ACTION_MERGE = "action_merge"; + public static final String ACTION_FAB_TAKE_PHOTO = "action_fab_take_photo"; /** * Used to quickly add a note, save, and perform backPress (eg. Tasker+Pushbullet) * */ - String ACTION_SEND_AND_EXIT = "action_send_and_exit"; - String ACTION_SEARCH_UNCOMPLETE_CHECKLISTS = "action_search_uncomplete_checklists"; - - String PREF_LANG = "settings_language"; - String PREF_LAST_UPDATE_CHECK = "last_update_check"; - String PREF_NAVIGATION = "navigation"; - String PREF_SORTING_COLUMN = "sorting_column"; - String PREF_PASSWORD = "password"; - String PREF_PASSWORD_QUESTION = "password_question"; - String PREF_PASSWORD_ANSWER = "password_answer"; - String PREF_KEEP_CHECKED = "keep_checked"; - String PREF_KEEP_CHECKMARKS = "show_checkmarks"; - String PREF_EXPANDED_VIEW = "expanded_view"; - String PREF_COLORS_APP_DEFAULT = "strip"; - String PREF_WIDGET_PREFIX = "widget_"; - String PREF_SHOW_UNCATEGORIZED = "settings_show_uncategorized"; - String PREF_AUTO_LOCATION = "settings_auto_location"; - String PREF_FILTER_PAST_REMINDERS = "settings_filter_past_reminders"; - String PREF_FILTER_ARCHIVED_IN_CATEGORIES = "settings_filter_archived_in_categories"; - String PREF_DYNAMIC_MENU = "settings_dynamic_menu"; - String PREF_CURRENT_APP_VERSION = "settings_current_app_version"; - String PREF_FAB_EXPANSION_BEHAVIOR = "settings_fab_expansion_behavior"; - String PREF_ATTACHMENTS_ON_BOTTOM = "settings_attachments_on_bottom"; - String PREF_SNOOZE_DEFAULT = "10"; - String PREF_TOUR_COMPLETE = "pref_tour_complete"; - String PREF_ENABLE_SWIPE = "settings_enable_swipe"; - String PREF_SEND_ANALYTICS = "settings_send_analytics"; - String PREF_PRETTIFIED_DATES = "settings_prettified_dates"; - String PREF_ENABLE_AUTOBACKUP = "settings_enable_autobackup"; - String PREF_ENABLE_FILE_LOGGING = "settings_enable_file_logging"; - String PREF_BACKUP_FOLDER_URI = "backup_folder"; - - String MIME_TYPE_IMAGE = "image/jpeg"; - String MIME_TYPE_AUDIO = "audio/amr"; - String MIME_TYPE_VIDEO = "video/mp4"; - String MIME_TYPE_SKETCH = "image/png"; - String MIME_TYPE_FILES = "file/*"; - - String MIME_TYPE_IMAGE_EXT = ".jpeg"; - String MIME_TYPE_AUDIO_EXT = ".amr"; - String MIME_TYPE_VIDEO_EXT = ".mp4"; - String MIME_TYPE_SKETCH_EXT = ".png"; - String MIME_TYPE_CONTACT_EXT = ".vcf"; - - String TIMESTAMP_UNIX_EPOCH = "0"; - String TIMESTAMP_UNIX_EPOCH_FAR = "18464193800000"; - - int MENU_SORT_GROUP_ID = 11998811; - - String MERGED_NOTES_SEPARATOR = "----------------------"; - String PROPERTIES_PARAMS_SEPARATOR = ","; - - String AUTO_BACKUP_DIR = "_autobackup"; - -} + public static final String ACTION_SEND_AND_EXIT = "action_send_and_exit"; + public static final String ACTION_SEARCH_UNCOMPLETE_CHECKLISTS = "action_search_uncomplete_checklists"; + + public static final String PREF_LANG = "settings_language"; + public static final String PREF_LAST_UPDATE_CHECK = "last_update_check"; + public static final String PREF_NAVIGATION = "navigation"; + public static final String PREF_SORTING_COLUMN = "sorting_column"; + public static final String PREF_PASSWORD = "password"; + public static final String PREF_PASSWORD_QUESTION = "password_question"; + public static final String PREF_PASSWORD_ANSWER = "password_answer"; + public static final String PREF_KEEP_CHECKED = "keep_checked"; + public static final String PREF_KEEP_CHECKMARKS = "show_checkmarks"; + public static final String PREF_EXPANDED_VIEW = "expanded_view"; + public static final String PREF_COLORS_APP_DEFAULT = "strip"; + public static final String PREF_WIDGET_PREFIX = "widget_"; + public static final String PREF_SHOW_UNCATEGORIZED = "settings_show_uncategorized"; + public static final String PREF_AUTO_LOCATION = "settings_auto_location"; + public static final String PREF_FILTER_PAST_REMINDERS = "settings_filter_past_reminders"; + public static final String PREF_FILTER_ARCHIVED_IN_CATEGORIES = "settings_filter_archived_in_categories"; + public static final String PREF_DYNAMIC_MENU = "settings_dynamic_menu"; + public static final String PREF_CURRENT_APP_VERSION = "settings_current_app_version"; + public static final String PREF_FAB_EXPANSION_BEHAVIOR = "settings_fab_expansion_behavior"; + public static final String PREF_ATTACHMENTS_ON_BOTTOM = "settings_attachments_on_bottom"; + public static final String PREF_SNOOZE_DEFAULT = "10"; + public static final String PREF_TOUR_COMPLETE = "pref_tour_complete"; + public static final String PREF_ENABLE_SWIPE = "settings_enable_swipe"; + public static final String PREF_SEND_ANALYTICS = "settings_send_analytics"; + public static final String PREF_PRETTIFIED_DATES = "settings_prettified_dates"; + public static final String PREF_ENABLE_AUTOBACKUP = "settings_enable_autobackup"; + public static final String PREF_ENABLE_FILE_LOGGING = "settings_enable_file_logging"; + public static final String PREF_BACKUP_FOLDER_URI = "backup_folder"; + + public static final String MIME_TYPE_IMAGE = "image/jpeg"; + public static final String MIME_TYPE_AUDIO = "audio/amr"; + public static final String MIME_TYPE_VIDEO = "video/mp4"; + public static final String MIME_TYPE_SKETCH = "image/png"; + public static final String MIME_TYPE_FILES = "file/*"; + + public static final String MIME_TYPE_IMAGE_EXT = ".jpeg"; + public static final String MIME_TYPE_AUDIO_EXT = ".amr"; + public static final String MIME_TYPE_VIDEO_EXT = ".mp4"; + public static final String MIME_TYPE_SKETCH_EXT = ".png"; + public static final String MIME_TYPE_CONTACT_EXT = ".vcf"; + + public static final String TIMESTAMP_UNIX_EPOCH = "0"; + public static final String TIMESTAMP_UNIX_EPOCH_FAR = "18464193800000"; + + public static final int MENU_SORT_GROUP_ID = 11998811; + + public static final String MERGED_NOTES_SEPARATOR = "----------------------"; + public static final String PROPERTIES_PARAMS_SEPARATOR = ","; + + public static final String AUTO_BACKUP_DIR = "_autobackup"; + + protected ConstantsBase() { + } +} \ No newline at end of file diff --git a/omniNotes/src/main/java/it/feio/android/omninotes/utils/PasswordHelper.java b/omniNotes/src/main/java/it/feio/android/omninotes/utils/PasswordHelper.java index f7a2d84f1..4d6f1eb68 100644 --- a/omniNotes/src/main/java/it/feio/android/omninotes/utils/PasswordHelper.java +++ b/omniNotes/src/main/java/it/feio/android/omninotes/utils/PasswordHelper.java @@ -36,103 +36,115 @@ import it.feio.android.omninotes.db.DbHelper; import it.feio.android.omninotes.models.PasswordValidator; import lombok.experimental.UtilityClass; - +import android.content.DialogInterface; @UtilityClass public class PasswordHelper { + public static void requestPassword(final Activity activity, final PasswordValidator passwordValidator) { + LayoutInflater inflater = activity.getLayoutInflater(); + View dialogView = inflater.inflate(R.layout.password_request_dialog_layout, null); + EditText passwordEditText = dialogView.findViewById(R.id.password_request); + if (passwordEditText == null) { + throw new IllegalStateException("View not found.Ensure the view exists in the layout file."); + } - public static void requestPassword(final Activity mActivity, - final PasswordValidator mPasswordValidator) { - LayoutInflater inflater = mActivity.getLayoutInflater(); - final View v = inflater.inflate(R.layout.password_request_dialog_layout, null); - final EditText passwordEditText = v.findViewById(R.id.password_request); - - MaterialDialog dialog = new MaterialDialog.Builder(mActivity) + MaterialDialog dialog = new MaterialDialog.Builder(activity) .autoDismiss(false) .title(R.string.insert_security_password) - .customView(v, false) + .customView(dialogView, false) .positiveText(R.string.ok) .positiveColorRes(R.color.colorPrimary) - .onPositive((dialog12, which) -> { - String storedPassword = Prefs.getString(PREF_PASSWORD, ""); - String password = passwordEditText.getText().toString(); - boolean result = Security.md5(password).equals(storedPassword); - - // In case password is ok dialog is dismissed and result sent to callback - if (result) { - KeyboardUtils.hideKeyboard(passwordEditText); - dialog12.dismiss(); - mPasswordValidator.onPasswordValidated(PasswordValidator.Result.SUCCEED); - // If password is wrong the auth flow is not interrupted and simply a message is shown - } else { - passwordEditText.setError(mActivity.getString(R.string.wrong_password)); - } - }) - .neutralText(mActivity.getResources().getString(R.string.password_forgot)) - .onNeutral((dialog13, which) -> { - PasswordHelper.resetPassword(mActivity); - mPasswordValidator.onPasswordValidated(PasswordValidator.Result.RESTORE); - dialog13.dismiss(); - }) + .onPositive((dialogInterface, which) -> validatePassword(activity, passwordEditText, passwordValidator, dialogInterface)) + .neutralText(activity.getString(R.string.password_forgot)) + .onNeutral((dialogInterface, which) -> handleForgotPassword(activity, passwordValidator, dialogInterface)) .build(); - dialog.setOnCancelListener(dialog1 -> { - KeyboardUtils.hideKeyboard(passwordEditText); - dialog1.dismiss(); - mPasswordValidator.onPasswordValidated(PasswordValidator.Result.FAIL); - }); + dialog.setOnCancelListener(dialogInterface -> handleCancel(passwordEditText, passwordValidator, dialogInterface)); passwordEditText.setOnEditorActionListener((textView, actionId, keyEvent) -> { - if (actionId == EditorInfo.IME_ACTION_DONE) { - dialog.getActionButton(DialogAction.POSITIVE).callOnClick(); - return true; - } - return false; + if (actionId == EditorInfo.IME_ACTION_DONE) { + dialog.getActionButton(DialogAction.POSITIVE).callOnClick(); + return true; + } + return false; }); dialog.show(); - new Handler().postDelayed(() -> KeyboardUtils.showKeyboard(passwordEditText), 100); - } +} +private static void validatePassword(Activity activity, EditText passwordEditText, + PasswordValidator passwordValidator, DialogInterface dialogInterface) { + String storedPassword = Prefs.getString(PREF_PASSWORD, ""); + String enteredPassword = passwordEditText.getText().toString(); + boolean isValid = Security.md5(enteredPassword).equals(storedPassword); + + if (isValid) { + KeyboardUtils.hideKeyboard(passwordEditText); + dialogInterface.dismiss(); + passwordValidator.onPasswordValidated(PasswordValidator.Result.SUCCEED); + } else { + passwordEditText.setError(activity.getString(R.string.wrong_password)); + } +} - public static void resetPassword(final Activity mActivity) { - View layout = mActivity.getLayoutInflater() - .inflate(R.layout.password_reset_dialog_layout, null); - final EditText answerEditText = layout.findViewById(R.id.reset_password_answer); +private static void handleForgotPassword(Activity activity, PasswordValidator passwordValidator, + DialogInterface dialogInterface) { + PasswordHelper.resetPassword(activity); + passwordValidator.onPasswordValidated(PasswordValidator.Result.RESTORE); + dialogInterface.dismiss(); +} - MaterialDialog dialog = new MaterialDialog.Builder(mActivity) - .title(Prefs.getString(PREF_PASSWORD_QUESTION, "")) - .customView(layout, false) - .autoDismiss(false) - .contentColorRes(R.color.text_color) - .positiveText(R.string.ok) - .onPositive((dialogElement, which) -> { - // When positive button is pressed answer correctness is checked +private static void handleCancel(EditText passwordEditText, PasswordValidator passwordValidator, + DialogInterface dialogInterface) { + KeyboardUtils.hideKeyboard(passwordEditText); + dialogInterface.dismiss(); + passwordValidator.onPasswordValidated(PasswordValidator.Result.FAIL); +} +public static void resetPassword(final Activity activity) { + View layout = activity.getLayoutInflater().inflate(R.layout.password_reset_dialog_layout, null); + final EditText answerEditText = layout.findViewById(R.id.reset_password_answer); + + if (answerEditText == null) { + throw new IllegalStateException("View not found.Ensure the view exists in the layout file."); + } + + MaterialDialog dialog = new MaterialDialog.Builder(activity) + .title(Prefs.getString(PREF_PASSWORD_QUESTION, "")) + .customView(layout, false) + .autoDismiss(false) + .contentColorRes(R.color.text_color) + .positiveText(R.string.ok) + .onPositive((dialogElement, which) -> { + // When positive button is pressed answer correctness is checked String oldAnswer = Prefs.getString(PREF_PASSWORD_ANSWER, ""); - String answer1 = answerEditText.getText().toString(); + String newAnswer = answerEditText.getText().toString(); // The check is done on password's hash stored in preferences - boolean result = Security.md5(answer1).equals(oldAnswer); - if (result) { - dialogElement.dismiss(); - removePassword(); + boolean isCorrect = Security.md5(newAnswer).equals(oldAnswer); + + if (isCorrect) { + dialogElement.dismiss(); + removePassword(); } else { - answerEditText.setError(mActivity.getString(R.string.wrong_answer)); + answerEditText.setError(activity.getString(R.string.wrong_answer)); } - }).build(); - dialog.show(); + }) + .build(); + + dialog.show(); - answerEditText.setOnEditorActionListener((textView, actionId, keyEvent) -> { + // Configura o listener apenas se answerEditText não for nulo + answerEditText.setOnEditorActionListener((textView, actionId, keyEvent) -> { if (actionId == EditorInfo.IME_ACTION_DONE) { - dialog.getActionButton(DialogAction.POSITIVE).callOnClick(); - return true; + dialog.getActionButton(DialogAction.POSITIVE).callOnClick(); + return true; } return false; - }); + }); - new Handler().postDelayed(() -> KeyboardUtils.showKeyboard(answerEditText), 100); - } + new Handler().postDelayed(() -> KeyboardUtils.showKeyboard(answerEditText), 100); +} public static void removePassword() { diff --git a/omniNotes/src/play/java/it/feio/android/omninotes/utils/Constants.java b/omniNotes/src/play/java/it/feio/android/omninotes/utils/Constants.java index 19acaa12d..1639a96b7 100644 --- a/omniNotes/src/play/java/it/feio/android/omninotes/utils/Constants.java +++ b/omniNotes/src/play/java/it/feio/android/omninotes/utils/Constants.java @@ -16,14 +16,17 @@ */ package it.feio.android.omninotes.utils; -public interface Constants extends ConstantsBase { +public final class Constants extends ConstantsBase { - String TAG = "Omni Notes"; - String EXTERNAL_STORAGE_FOLDER = "Omni Notes"; - String PACKAGE = "it.feio.android.omninotes"; + public static final String TAG = "Omni Notes"; + public static final String EXTERNAL_STORAGE_FOLDER = "Omni Notes"; + public static final String PACKAGE = "it.feio.android.omninotes"; - String CHANNEL_BACKUPS_ID = PACKAGE + ".backups"; - String CHANNEL_REMINDERS_ID = PACKAGE + ".reminders"; - String CHANNEL_PINNED_ID = PACKAGE + ".pinned"; + public static final String CHANNEL_BACKUPS_ID = PACKAGE + ".backups"; + public static final String CHANNEL_REMINDERS_ID = PACKAGE + ".reminders"; + public static final String CHANNEL_PINNED_ID = PACKAGE + ".pinned"; -} + private Constants() { + throw new AssertionError("Cannot be instantiated"); + } +} \ No newline at end of file