From 2c6a5674e52a397db723ecc4a44cd7615d742997 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 8 Feb 2018 18:03:14 +0300 Subject: [PATCH 1/9] Initial commit. --- .gitignore | 6 + README.md | 5 + app/app.iml | 159 +++++++ app/build.gradle | 42 ++ app/proguard-rules.pro | 21 + .../ExampleInstrumentedTest.java | 26 ++ app/src/main/AndroidManifest.xml | 84 ++++ .../controller/Controller.java | 296 +++++++++++++ .../controller/ExamDatabaseController.java | 175 ++++++++ .../HomeworkDatabaseController.java | 242 ++++++++++ .../ScheduleDatabaseController.java | 114 +++++ .../controller/StoredDataController.java | 74 ++++ .../StudyMaterialDatabaseController.java | 135 ++++++ .../controller/SubjectDatabaseController.java | 112 +++++ .../UnrecognizedCreditFormException.java | 5 + .../model/CreditByAcceptedHomeworks.java | 35 ++ .../model/CreditByPercent.java | 36 ++ .../notdeadbydeadline/model/CreditEnum.java | 6 + .../model/DetailedEntry.java | 11 + .../model/DetailedTimedEntry.java | 14 + .../notdeadbydeadline/model/Exam.java | 96 ++++ .../notdeadbydeadline/model/ExamEnum.java | 17 + .../notdeadbydeadline/model/Homework.java | 170 +++++++ .../model/ScheduleEntry.java | 75 ++++ .../model/StudyMaterial.java | 62 +++ .../model/SubjectCredit.java | 60 +++ .../model/WeekParityEnum.java | 22 + .../ui/AddHomeworkActivity.java | 415 ++++++++++++++++++ .../ui/AddScheduleEntryActivity.java | 255 +++++++++++ .../ui/DeadlinesActivity.java | 282 ++++++++++++ .../ui/DisplayHomeworkActivity.java | 102 +++++ .../ui/HomeworkActivity.java | 146 ++++++ .../ui/HomeworkListViewAdapter.java | 89 ++++ .../notdeadbydeadline/ui/MainActivity.java | 221 ++++++++++ .../ui/ScheduleActivity.java | 319 ++++++++++++++ .../ui/ScheduleListViewAdapter.java | 77 ++++ .../ui/utilities/AbstractDatePicker.java | 39 ++ .../ui/utilities/AbstractTimePicker.java | 39 ++ .../ui/utilities/ListViewUtility.java | 39 ++ .../ui/utilities/WeekDayEnum.java | 5 + .../drawable-v24/ic_launcher_foreground.xml | 34 ++ .../res/drawable/ic_launcher_background.xml | 170 +++++++ .../res/drawable/ic_note_add_white_24dp.xml | 9 + app/src/main/res/drawable/side_nav_bar.xml | 9 + .../main/res/layout/activity_add_homework.xml | 112 +++++ .../layout/activity_add_schedule_entry.xml | 25 ++ .../main/res/layout/activity_deadlines.xml | 25 ++ .../res/layout/activity_display_homework.xml | 25 ++ app/src/main/res/layout/activity_homework.xml | 25 ++ app/src/main/res/layout/activity_main.xml | 25 ++ app/src/main/res/layout/activity_schedule.xml | 25 ++ app/src/main/res/layout/app_bar_deadlines.xml | 25 ++ app/src/main/res/layout/app_bar_homework.xml | 34 ++ app/src/main/res/layout/app_bar_main.xml | 25 ++ app/src/main/res/layout/app_bar_schedule.xml | 34 ++ .../main/res/layout/content_add_homework.xml | 11 + .../res/layout/content_add_schedule_entry.xml | 117 +++++ app/src/main/res/layout/content_deadlines.xml | 290 ++++++++++++ .../res/layout/content_display_homework.xml | 23 + app/src/main/res/layout/content_homework.xml | 20 + app/src/main/res/layout/content_main.xml | 72 +++ app/src/main/res/layout/content_schedule.xml | 235 ++++++++++ .../layout/custom_deadline_listview_entry.xml | 13 + .../layout/custom_homework_listview_entry.xml | 13 + .../layout/custom_homework_listview_item.xml | 24 + .../custom_mainscreen_listview_entry.xml | 13 + .../layout/custom_schedule_listview_item.xml | 24 + .../custom_textview_for_bigger_listview.xml | 14 + .../main/res/layout/nav_header_deadlines.xml | 22 + .../main/res/layout/nav_header_homework.xml | 23 + app/src/main/res/layout/nav_header_main.xml | 29 ++ .../main/res/layout/nav_header_schedule.xml | 22 + .../res/menu/activity_deadlines_drawer.xml | 24 + .../res/menu/activity_homework_drawer.xml | 25 ++ .../main/res/menu/activity_main_drawer.xml | 25 ++ .../res/menu/activity_schedule_drawer.xml | 25 ++ app/src/main/res/menu/deadlines.xml | 9 + app/src/main/res/menu/homework.xml | 9 + app/src/main/res/menu/listview_item_menu.xml | 11 + app/src/main/res/menu/main.xml | 9 + app/src/main/res/menu/schedule.xml | 9 + app/src/main/res/menu/week_day_menu.xml | 27 ++ .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5024 bytes app/src/main/res/mipmap-hdpi/ndbd.png | Bin 0 -> 2751 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2858 bytes app/src/main/res/mipmap-mdpi/ndbd.png | Bin 0 -> 1858 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7098 bytes app/src/main/res/mipmap-xhdpi/ndbd.png | Bin 0 -> 3451 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10676 bytes app/src/main/res/mipmap-xxhdpi/ndbd.png | Bin 0 -> 4260 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 15523 bytes app/src/main/res/mipmap-xxxhdpi/ndbd.png | Bin 0 -> 4246 bytes app/src/main/res/values/colors.xml | 6 + app/src/main/res/values/dimens.xml | 8 + app/src/main/res/values/strings.xml | 69 +++ app/src/main/res/values/styles.xml | 20 + app/src/main/res/xml/backup_descriptor.xml | 17 + .../notdeadbydeadline/ExampleUnitTest.java | 17 + build.gradle | 27 ++ gradle.properties | 17 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 160 +++++++ gradlew.bat | 90 ++++ java_project.iml | 19 + local.properties | 11 + settings.gradle | 1 + 108 files changed, 6341 insertions(+) create mode 100644 app/app.iml create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/ru/spbau/group202/notdeadbydeadline/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/Controller.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/ExamDatabaseController.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/HomeworkDatabaseController.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/ScheduleDatabaseController.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/StoredDataController.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/StudyMaterialDatabaseController.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/SubjectDatabaseController.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/UnrecognizedCreditFormException.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/CreditByAcceptedHomeworks.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/CreditByPercent.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/CreditEnum.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/DetailedEntry.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/DetailedTimedEntry.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/Exam.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/ExamEnum.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/Homework.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/ScheduleEntry.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/StudyMaterial.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/SubjectCredit.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/WeekParityEnum.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/AddHomeworkActivity.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/AddScheduleEntryActivity.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/DeadlinesActivity.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/DisplayHomeworkActivity.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/HomeworkActivity.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/HomeworkListViewAdapter.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/MainActivity.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/ScheduleActivity.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/ScheduleListViewAdapter.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/AbstractDatePicker.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/AbstractTimePicker.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/ListViewUtility.java create mode 100644 app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/WeekDayEnum.java create mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/drawable/ic_note_add_white_24dp.xml create mode 100644 app/src/main/res/drawable/side_nav_bar.xml create mode 100644 app/src/main/res/layout/activity_add_homework.xml create mode 100644 app/src/main/res/layout/activity_add_schedule_entry.xml create mode 100644 app/src/main/res/layout/activity_deadlines.xml create mode 100644 app/src/main/res/layout/activity_display_homework.xml create mode 100644 app/src/main/res/layout/activity_homework.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/activity_schedule.xml create mode 100644 app/src/main/res/layout/app_bar_deadlines.xml create mode 100644 app/src/main/res/layout/app_bar_homework.xml create mode 100644 app/src/main/res/layout/app_bar_main.xml create mode 100644 app/src/main/res/layout/app_bar_schedule.xml create mode 100644 app/src/main/res/layout/content_add_homework.xml create mode 100644 app/src/main/res/layout/content_add_schedule_entry.xml create mode 100644 app/src/main/res/layout/content_deadlines.xml create mode 100644 app/src/main/res/layout/content_display_homework.xml create mode 100644 app/src/main/res/layout/content_homework.xml create mode 100644 app/src/main/res/layout/content_main.xml create mode 100644 app/src/main/res/layout/content_schedule.xml create mode 100644 app/src/main/res/layout/custom_deadline_listview_entry.xml create mode 100644 app/src/main/res/layout/custom_homework_listview_entry.xml create mode 100644 app/src/main/res/layout/custom_homework_listview_item.xml create mode 100644 app/src/main/res/layout/custom_mainscreen_listview_entry.xml create mode 100644 app/src/main/res/layout/custom_schedule_listview_item.xml create mode 100644 app/src/main/res/layout/custom_textview_for_bigger_listview.xml create mode 100644 app/src/main/res/layout/nav_header_deadlines.xml create mode 100644 app/src/main/res/layout/nav_header_homework.xml create mode 100644 app/src/main/res/layout/nav_header_main.xml create mode 100644 app/src/main/res/layout/nav_header_schedule.xml create mode 100644 app/src/main/res/menu/activity_deadlines_drawer.xml create mode 100644 app/src/main/res/menu/activity_homework_drawer.xml create mode 100644 app/src/main/res/menu/activity_main_drawer.xml create mode 100644 app/src/main/res/menu/activity_schedule_drawer.xml create mode 100644 app/src/main/res/menu/deadlines.xml create mode 100644 app/src/main/res/menu/homework.xml create mode 100644 app/src/main/res/menu/listview_item_menu.xml create mode 100644 app/src/main/res/menu/main.xml create mode 100644 app/src/main/res/menu/schedule.xml create mode 100644 app/src/main/res/menu/week_day_menu.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-hdpi/ndbd.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-mdpi/ndbd.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xhdpi/ndbd.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ndbd.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ndbd.png create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 app/src/main/res/xml/backup_descriptor.xml create mode 100644 app/src/test/java/ru/spbau/group202/notdeadbydeadline/ExampleUnitTest.java create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 java_project.iml create mode 100644 local.properties create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore index 345e61a..73304fc 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ .idea/**/workspace.xml .idea/**/tasks.xml .idea/dictionaries +app/build/ # Sensitive or high-churn files: .idea/**/dataSources/ @@ -47,3 +48,8 @@ com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties + +# Binary files +**.bin +**.lock +**.rawproto \ No newline at end of file diff --git a/README.md b/README.md index bf78fb0..c47fc1e 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,8 @@ Java project; fall semester ## Not Dead by Deadline An app to help you organize your study life and not die by the time the deadline rolls around. + +### Features +* Adding new homeworks +* Displaying all current homeworks by subject +* Displaying all current/nearest deadlines diff --git a/app/app.iml b/app/app.iml new file mode 100644 index 0000000..9eb1ed6 --- /dev/null +++ b/app/app.iml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..3977fb1 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,42 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 26 + defaultConfig { + applicationId "ru.spbau.group202.notdeadbydeadline" + minSdkVersion 22 + targetSdkVersion 26 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + multiDexEnabled true + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + lintOptions { + abortOnError false + } +} + +dependencies { + implementation "com.google.code.gson:gson:2.8.0" + implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.0' + implementation 'com.android.support:appcompat-v7:26.1.0' + implementation 'com.android.support:support-v4:26.1.0' + implementation 'com.android.support:design:26.1.0' + implementation 'com.android.support.constraint:constraint-layout:1.0.2' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.1' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' + implementation 'org.jetbrains:annotations-java5:15.0' + implementation 'net.danlew:android.joda:2.9.9.1' + implementation 'com.android.support:multidex:1.0.2' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/androidTest/java/ru/spbau/group202/notdeadbydeadline/ExampleInstrumentedTest.java b/app/src/androidTest/java/ru/spbau/group202/notdeadbydeadline/ExampleInstrumentedTest.java new file mode 100644 index 0000000..af8e055 --- /dev/null +++ b/app/src/androidTest/java/ru/spbau/group202/notdeadbydeadline/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package ru.spbau.group202.notdeadbydeadline; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("ru.spbau.group202.notdeadbydeadline", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..097cf5f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/Controller.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/Controller.java new file mode 100644 index 0000000..1bb6419 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/Controller.java @@ -0,0 +1,296 @@ +package ru.spbau.group202.notdeadbydeadline.controller; + +import android.content.Context; + +import org.jetbrains.annotations.NotNull; +import org.joda.time.LocalDate; +import org.joda.time.LocalDateTime; +import org.apache.commons.collections4.ListUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import ru.spbau.group202.notdeadbydeadline.model.CreditEnum; +import ru.spbau.group202.notdeadbydeadline.model.DetailedEntry; +import ru.spbau.group202.notdeadbydeadline.model.DetailedTimedEntry; +import ru.spbau.group202.notdeadbydeadline.model.Homework; +import ru.spbau.group202.notdeadbydeadline.model.ScheduleEntry; +import ru.spbau.group202.notdeadbydeadline.model.StudyMaterial; +import ru.spbau.group202.notdeadbydeadline.model.SubjectCredit; +import ru.spbau.group202.notdeadbydeadline.model.WeekParityEnum; +import ru.spbau.group202.notdeadbydeadline.model.Exam; +import ru.spbau.group202.notdeadbydeadline.model.ExamEnum; + +public class Controller { + private static StoredDataController settings; + private static SubjectDatabaseController subjectDatabase; + private static Set subjectList; + + @NotNull + public static List getSubjectList() { + return new ArrayList<>(subjectList); + } + + public static void setWeekPairity(boolean isInversed) { + settings.saveWeekPairity(isInversed); + } + + public static class AcademicProgressController { + @NotNull + public List calculateProgress(@NotNull String subject) throws UnrecognizedCreditFormException { + SubjectCredit subjectCredit = subjectDatabase.getSubjectCredit(subject); + return subjectCredit.calculateProgress(HomeworkController.homeworkDatabase.getPassedHomeworksBySubject(subject), + ExamController.examDatabase.getExamsBySubject(subject)); + } + + public void setSubjectCreditForm(@NotNull String subject, @NotNull CreditEnum credit) { + subjectDatabase.setSubjectCreditForm(subject, credit); + } + } + + public static class HomeworkController { + private static HomeworkDatabaseController homeworkDatabase; + + @NotNull + public static List> getHomeworksBySubject(@NotNull String subject) { + return getEntriesDetailList(homeworkDatabase.getHomeworksBySubject(subject)); + } + + @NotNull + public static List> getPassedHomeworksBySubject(@NotNull String subject) { + return getEntriesDetailList(homeworkDatabase.getPassedHomeworksBySubject(subject)); + } + + @NotNull + public static List> getHomeworksByDay(@NotNull LocalDate date) { + return getEntriesDetailList(homeworkDatabase.getHomeworksByDay(date)); + } + + public static void addHomework(@NotNull LocalDateTime deadline, @NotNull String subject, + int regularity, String description, String howToSend, + double expectedScore, @NotNull ArrayList materials) { + int id = settings.getTotalNumberOfHW(); + Homework homework = new Homework(deadline, subject, regularity, description, + howToSend, expectedScore, id, materials); + homeworkDatabase.addHomework(homework); + settings.saveTotalNumberOfHW(++id); + + if (subjectList.add(subject)) { + subjectDatabase.addSubject(subject, CreditEnum.NOT_STATED, -1); + } + } + + public static void deleteHomeworkById(int id) { + homeworkDatabase.deleteHomeworkById(id); + } + + public static void setHomeworkScoreById(int id, int score) { + homeworkDatabase.setScoreById(id, score); + } + + public static void editHomeworkById(int id, @NotNull LocalDateTime deadline, @NotNull String subject, + int regularity, String description, String howToSend, + double expectedScore, @NotNull ArrayList materials) { + deleteHomeworkById(id); + Homework homework = new Homework(deadline, subject, regularity, description, + howToSend, expectedScore, id, materials); + homeworkDatabase.addHomework(homework); + + if (subjectList.add(subject)) { + subjectDatabase.addSubject(subject, CreditEnum.NOT_STATED, -1); + } + } + + @NotNull + public static List getHomeworkById(int id) { + List homeworks = (homeworkDatabase.getHomeworkById(id)); + List entriesDetailList = getEntriesDetailList(homeworks).get(0); + entriesDetailList.add(0, homeworks.get(0).getSubject()); + return entriesDetailList; + } + + @NotNull + public static List> getDeadlinesByDay(@NotNull LocalDate date) { + return getEntriesDetailList(toDeadlines(homeworkDatabase.getHomeworksByDay(date))); + } + + public static void generateHomeworks() { + LocalDate today = LocalDate.now(); + for (Homework homework : homeworkDatabase.getHomeworksByDay(today)) { + if (homework.getRegularity() != 0) { + int id = settings.getTotalNumberOfHW(); + homeworkDatabase.addHomework(homework.generateNewHomeworkById(id)); + settings.saveTotalNumberOfHW(++id); + } + } + } + + @NotNull + private static List toDeadlines(@NotNull List homeworks) { + List deadlines = new ArrayList<>(); + for (Homework homework : homeworks) { + deadlines.add(homework.getDeadline()); + } + return deadlines; + } + } + + public static class ScheduleController { + private static ScheduleDatabaseController scheduleDatabase; + + @NotNull + public static List> getScheduleByDay(LocalDate day) { + WeekParityEnum weekParity = WeekParityEnum.values()[day.getWeekOfWeekyear() % 2]; + if (settings.getParityOfWeek()) { + weekParity = weekParity.inverse(); + } + + List classes = scheduleDatabase.getDaySchedule(day.getDayOfWeek() - 1, + weekParity); + List exams = ExamController.examDatabase.getExamsByDay(day); + List detailedEntryList = ListUtils.union(exams, classes); + Collections.sort(detailedEntryList); + + return getEntriesDetailList(detailedEntryList); + } + + public static void addScheduleEntry(@NotNull String subject, int dayOfWeek, int hour, + int minute, @NotNull WeekParityEnum weekParity, + @NotNull String auditorium, @NotNull String teacher) { + int id = settings.getTotalNumberOfScheduleEntries(); + ScheduleEntry scheduleEntry = new ScheduleEntry(subject, dayOfWeek, hour, minute, + + weekParity, auditorium, teacher, id); + scheduleDatabase.addScheduleEntry(scheduleEntry); + settings.saveTotalNumberOfScheduleEntries(++id); + } + + public static void deleteScheduleEntryById(int id) { + scheduleDatabase.deleteScheduleEntryById(id); + } + + } + + public static class ExamController { + private static ExamDatabaseController examDatabase; + + @NotNull + public static List> getWorksBySubject(@NotNull String subject) { + return getEntriesDetailList(examDatabase.getExamsBySubject(subject)); + } + + @NotNull + public static List> getWorksByDay(@NotNull LocalDate date) { + return getEntriesDetailList(examDatabase.getExamsByDay(date)); + } + + public static void addWork(@NotNull LocalDateTime date, @NotNull String subject, + @NotNull ExamEnum examEnum, String description) { + int id = settings.getTotalNumberOfWorks(); + Exam exam = new Exam(subject, description, date, examEnum, id); + examDatabase.addExam(exam); + settings.saveTotalNumberOfWorks(++id); + + if (subjectList.add(subject)) { + subjectDatabase.addSubject(subject, CreditEnum.NOT_STATED, -1); + } + } + + public static void deleteWorkById(int id) { + examDatabase.deleteExamById(id); + } + + public static void setWorkAcceptedById(int id, boolean isAccepted) { + examDatabase.setAcceptedById(id, isAccepted); + } + + public static void editWorkById(int id, @NotNull LocalDateTime date, @NotNull String subject, + @NotNull ExamEnum examEnum, String description) { + deleteWorkById(id); + Exam exam = new Exam(subject, description, date, examEnum, id); + examDatabase.addExam(exam); + + if (subjectList.add(subject)) { + subjectDatabase.addSubject(subject, CreditEnum.NOT_STATED, -1); + } + } + + @NotNull + public static List getWorkById(int id) { + return getEntriesDetailList(examDatabase.getExamById(id)).get(0); + } + } + + public static class StudyMaterialsController { + private static StudyMaterialDatabaseController studyMaterialDatabase; + + @NotNull + public static List> getStudyMaterialsBySubject(@NotNull String subject) { + return getEntriesDetailList(studyMaterialDatabase.getStudyMaterialsBySubject(subject)); + } + + @NotNull + public static List> getStudyMaterialsByTerm(int term) { + return getEntriesDetailList(studyMaterialDatabase.getStudyMaterialsByTerm(term)); + } + + public static void addStudyMaterial(@NotNull String subject, int term, @NotNull String URL, + @NotNull String path) { + int id = settings.getTotalNumberOfStudyMaterials(); + StudyMaterial studyMaterial = new StudyMaterial(subject, term, URL, path, id); + studyMaterialDatabase.addStudyMaterial(studyMaterial); + settings.saveTotalNumberOfStudyMaterials(++id); + + if (!subject.equals("Not stated") && subjectList.add(subject)) { + subjectDatabase.addSubject(subject, CreditEnum.NOT_STATED, -1); + } + } + + public static void deleteStudyMaterialById(int id) { + studyMaterialDatabase.deleteStudyMaterialById(id); + } + + public static void editStudyMaterialById(int id, @NotNull String subject, int term, + @NotNull String URL, @NotNull String path) { + deleteStudyMaterialById(id); + StudyMaterial studyMaterial = new StudyMaterial(subject, term, URL, path, id); + studyMaterialDatabase.addStudyMaterial(studyMaterial); + + if (!subject.equals("Not stated") && subjectList.add(subject)) { + subjectDatabase.addSubject(subject, CreditEnum.NOT_STATED, -1); + } + } + + @NotNull + public static List getStudyMaterialById(int id) { + return getEntriesDetailList(studyMaterialDatabase.getStudyMaterialById(id)).get(0); + } + + } + + public static void createDatabases(@NotNull Context context) { + HomeworkController.homeworkDatabase = new HomeworkDatabaseController(context); + subjectDatabase = new SubjectDatabaseController(context); + ScheduleController.scheduleDatabase = new ScheduleDatabaseController(context); + ExamController.examDatabase = new ExamDatabaseController(context); + StudyMaterialsController.studyMaterialDatabase = new StudyMaterialDatabaseController(context); + settings = new StoredDataController(context); + subjectList = new HashSet<>(); + subjectList.addAll(subjectDatabase.getAllSubjects()); + HomeworkController.generateHomeworks(); + } + + @NotNull + private static List> getEntriesDetailList(@NotNull List entries) { + List> entriesDetails = new ArrayList<>(); + for (T entry : entries) { + entriesDetails.add(entry.getDetails()); + } + return entriesDetails; + } + + +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/ExamDatabaseController.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/ExamDatabaseController.java new file mode 100644 index 0000000..af0f726 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/ExamDatabaseController.java @@ -0,0 +1,175 @@ +package ru.spbau.group202.notdeadbydeadline.controller; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; + +import org.jetbrains.annotations.NotNull; +import org.joda.time.LocalDate; +import org.joda.time.LocalDateTime; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import ru.spbau.group202.notdeadbydeadline.model.Exam; +import ru.spbau.group202.notdeadbydeadline.model.ExamEnum; + + +public class ExamDatabaseController extends SQLiteOpenHelper { + private static final String DATABASE_NAME = "Exams"; + private static final int DATABASE_VERSION = 1; + private static final String COLUMN_NAME_ID = "ID"; + private static final String COLUMN_NAME_SUBJECT = "SUBJECT"; + private static final String COLUMN_NAME_YEAR = "YEAR"; + private static final String COLUMN_NAME_MONTH = "MONTH"; + private static final String COLUMN_NAME_DAY = "DAY"; + private static final String COLUMN_NAME_HOUR = "HOUR"; + private static final String COLUMN_NAME_MINUTE = "MINUTE"; + private static final String COLUMN_NAME_DESCRIPTION = "DESCRIPTION"; + private static final String COLUMN_NAME_EXAM_TYPE = "EXAM_TYPE"; + private static final String COLUMN_NAME_IS_ACCEPTED = "IS_ACCEPTED"; + + public ExamDatabaseController(@NotNull Context context) { + super(context.getApplicationContext(), DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + Log.d("Database", "onCreate database"); + db.execSQL("CREATE TABLE " + DATABASE_NAME + " (" + + COLUMN_NAME_ID + " INTEGER PRIMARY KEY, " + + COLUMN_NAME_SUBJECT + " TEXT, " + + COLUMN_NAME_YEAR + " INTEGER, " + + COLUMN_NAME_MONTH + " INTEGER, " + + COLUMN_NAME_DAY + " INTEGER, " + + COLUMN_NAME_HOUR + " INTEGER, " + + COLUMN_NAME_MINUTE + " INTEGER, " + + COLUMN_NAME_DESCRIPTION + " TEXT, " + + COLUMN_NAME_EXAM_TYPE + " INTEGER, " + + COLUMN_NAME_IS_ACCEPTED + " INTEGER" + ");"); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldDATABASE_VERSION, int newDATABASE_VERSION) { + db.execSQL("DROP TABLE IF EXISTS " + DATABASE_NAME); + onCreate(db); + } + + @NotNull + private Exam getExamByCursor(@NotNull Cursor cursor) { + int id = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_ID)); + String subject = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_SUBJECT)); + int year = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_YEAR)); + int month = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_MONTH)); + int day = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_DAY)); + int hour = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_HOUR)); + int minute = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_MINUTE)); + String description = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_DESCRIPTION)); + int examType = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_EXAM_TYPE)); + boolean isAccepted = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_IS_ACCEPTED)) == 1; + + LocalDateTime date = new LocalDateTime(year, month, day, hour, minute); + Exam exam = new Exam(subject, description, date, ExamEnum.values()[examType], id); + exam.setAccepted(isAccepted); + return exam; + } + + public void addExam(@NotNull Exam exam) { + try (SQLiteDatabase database = this.getWritableDatabase()) { + ContentValues values = new ContentValues(); + values.put(COLUMN_NAME_ID, exam.getId()); + values.put(COLUMN_NAME_SUBJECT, exam.getSubject()); + values.put(COLUMN_NAME_YEAR, exam.getYear()); + values.put(COLUMN_NAME_MONTH, exam.getMonth()); + values.put(COLUMN_NAME_DAY, exam.getDay()); + values.put(COLUMN_NAME_HOUR, exam.getHour()); + values.put(COLUMN_NAME_MINUTE, exam.getMinute()); + values.put(COLUMN_NAME_DESCRIPTION, exam.getDescription()); + values.put(COLUMN_NAME_EXAM_TYPE, exam.getExamType().ordinal()); + values.put(COLUMN_NAME_IS_ACCEPTED, exam.isAccepted() ? 1 : 0); + long rowId = database.insert(DATABASE_NAME, null, values); + Log.d("Database", "inserted row number " + rowId); + } + } + + @NotNull + public List getExamsBySubject(@NotNull String subject) { + String query = "SELECT * FROM " + DATABASE_NAME + + " WHERE " + COLUMN_NAME_SUBJECT + "=" + "?"; + List exams = new ArrayList<>(); + String[] selectionArgs = new String[]{String.valueOf(subject)}; + + try (SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery(query, selectionArgs)) { + if (cursor != null && cursor.moveToFirst()) { + do { + exams.add(getExamByCursor(cursor)); + } while (cursor.moveToNext()); + } + } + + Collections.sort(exams); + return exams; + } + + @NotNull + public List getExamsByDay(LocalDate date) { + String query = "SELECT * FROM " + DATABASE_NAME + " WHERE " + COLUMN_NAME_YEAR + "=? " + + "AND " + COLUMN_NAME_MONTH + "=? " + "AND " + COLUMN_NAME_DAY + "=?" + + "ORDER BY " + COLUMN_NAME_HOUR + ", " + COLUMN_NAME_MINUTE + " ASC"; + String[] selectionArgs = new String[]{String.valueOf(date.getYear()), + String.valueOf(date.getMonthOfYear()), String.valueOf(date.getDayOfMonth())}; + List exams = new ArrayList<>(); + + try (SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery(query, selectionArgs)) { + if (cursor != null && cursor.moveToFirst()) { + do { + Exam exam = getExamByCursor(cursor); + exams.add(exam); + } while (cursor.moveToNext()); + } + } + + return exams; + } + + public void deleteExamById(int id) { + try (SQLiteDatabase database = this.getWritableDatabase()) { + database.delete(DATABASE_NAME, COLUMN_NAME_ID + " = ?", + new String[]{String.valueOf(id)}); + } + } + + public void setAcceptedById(int id, boolean isAccepted) { + try (SQLiteDatabase database = this.getWritableDatabase()) { + ContentValues values = new ContentValues(); + values.put(COLUMN_NAME_IS_ACCEPTED, isAccepted); + database.update(DATABASE_NAME, values, COLUMN_NAME_ID + " = ?", + new String[]{String.valueOf(id)}); + } + } + + @NotNull + public List getExamById(int id) { + String query = "SELECT * FROM " + DATABASE_NAME + " WHERE " + COLUMN_NAME_ID + "=?"; + String[] selectionArgs = new String[]{String.valueOf(id)}; + List exams = new ArrayList<>(); + + try (SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery(query, selectionArgs)) { + if (cursor != null && cursor.moveToFirst()) { + do { + Exam exam = getExamByCursor(cursor); + exams.add(exam); + } while (cursor.moveToNext()); + } + } + + return exams; + } +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/HomeworkDatabaseController.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/HomeworkDatabaseController.java new file mode 100644 index 0000000..ac12783 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/HomeworkDatabaseController.java @@ -0,0 +1,242 @@ +package ru.spbau.group202.notdeadbydeadline.controller; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import org.jetbrains.annotations.NotNull; +import org.joda.time.LocalDate; +import org.joda.time.LocalDateTime; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import ru.spbau.group202.notdeadbydeadline.model.Homework; + +public class HomeworkDatabaseController extends SQLiteOpenHelper { + private static final String DATABASE_NAME = "Homeworks"; + private static final int DATABASE_VERSION = 1; + private static final String COLUMN_NAME_ID = "ID"; + private static final String COLUMN_NAME_SUBJECT = "SUBJECT"; + private static final String COLUMN_NAME_YEAR = "YEAR"; + private static final String COLUMN_NAME_MONTH = "MONTH"; + private static final String COLUMN_NAME_DAY = "DAY"; + private static final String COLUMN_NAME_HOUR = "HOUR"; + private static final String COLUMN_NAME_MINUTE = "MINUTE"; + private static final String COLUMN_NAME_REGULARITY = "REGULARITY"; + private static final String COLUMN_NAME_EXPECTED_SCORE = "EXPECTED_SCORE"; + private static final String COLUMN_NAME_ACTUAL_SCORE = "ACTUAL_SCORE"; + private static final String COLUMN_NAME_DESCRIPTION = "DESCRIPTION"; + private static final String COLUMN_NAME_HOW_TO_SEND = "HOW_TO_SEND"; + private static final String COLUMN_NAME_MATERIALS = "MATERIALS"; + + public HomeworkDatabaseController(@NotNull Context context) { + super(context.getApplicationContext(), DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + Log.d("Database", "onCreate database"); + db.execSQL("CREATE TABLE " + DATABASE_NAME + " (" + + COLUMN_NAME_ID + " INTEGER PRIMARY KEY, " + + COLUMN_NAME_SUBJECT + " TEXT, " + + COLUMN_NAME_YEAR + " INTEGER, " + + COLUMN_NAME_MONTH + " INTEGER, " + + COLUMN_NAME_DAY + " INTEGER, " + + COLUMN_NAME_HOUR + " INTEGER, " + + COLUMN_NAME_MINUTE + " INTEGER, " + + COLUMN_NAME_REGULARITY + " INTEGER, " + + COLUMN_NAME_EXPECTED_SCORE + " REAL, " + + COLUMN_NAME_ACTUAL_SCORE + " INTEGER, " + + COLUMN_NAME_DESCRIPTION + " TEXT, " + + COLUMN_NAME_HOW_TO_SEND + " TEXT, " + + COLUMN_NAME_MATERIALS + " TEXT" + ");"); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldDATABASE_VERSION, int newDATABASE_VERSION) { + db.execSQL("DROP TABLE IF EXISTS " + DATABASE_NAME); + onCreate(db); + } + + @NotNull + private Homework getHomeworkByCursor(@NotNull Cursor cursor) { + int id = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_ID)); + String subject = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_SUBJECT)); + int year = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_YEAR)); + int month = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_MONTH)); + int day = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_DAY)); + int hour = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_HOUR)); + int minute = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_MINUTE)); + int regularity = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_REGULARITY)); + double expectedScore = cursor.getDouble(cursor.getColumnIndex(COLUMN_NAME_EXPECTED_SCORE)); + int actualScore = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_ACTUAL_SCORE)); + String description = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_DESCRIPTION)); + String howToSend = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_HOW_TO_SEND)); + String gsonMaterials = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_MATERIALS)); + ArrayList materials = new Gson().fromJson(gsonMaterials, + new TypeToken>() { + }.getType()); + + + LocalDateTime deadline = new LocalDateTime(year, month, day, hour, minute); + Homework homework = new Homework(deadline, subject, regularity, description, howToSend, + expectedScore, id, materials); + homework.setActualScore(actualScore); + return homework; + } + + public void addHomework(@NotNull Homework homework) { + try (SQLiteDatabase database = this.getWritableDatabase()) { + ContentValues values = new ContentValues(); + values.put(COLUMN_NAME_ID, homework.getId()); + values.put(COLUMN_NAME_SUBJECT, homework.getSubject()); + values.put(COLUMN_NAME_YEAR, homework.getYear()); + values.put(COLUMN_NAME_MONTH, homework.getMonth()); + values.put(COLUMN_NAME_DAY, homework.getDay()); + values.put(COLUMN_NAME_HOUR, homework.getHour()); + values.put(COLUMN_NAME_MINUTE, homework.getMinute()); + values.put(COLUMN_NAME_REGULARITY, homework.getRegularity()); + values.put(COLUMN_NAME_EXPECTED_SCORE, homework.getExpectedScore()); + values.put(COLUMN_NAME_ACTUAL_SCORE, homework.getActualScore()); + values.put(COLUMN_NAME_DESCRIPTION, homework.getDescription()); + values.put(COLUMN_NAME_HOW_TO_SEND, homework.getHowToSend()); + values.put(COLUMN_NAME_MATERIALS, new Gson().toJson(homework.getMaterials())); + long rowId = database.insert(DATABASE_NAME, null, values); + Log.d("Database", "inserted row number " + rowId); + } + } + + @NotNull + public List getActualHomeworks() { + List homeworks = new ArrayList<>(); + try (SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery("SELECT * FROM " + DATABASE_NAME, null)) { + if (cursor != null && cursor.moveToFirst()) { + do { + Homework homework = getHomeworkByCursor(cursor); + if (!homework.hasPassed()) { + homeworks.add(homework); + } + } while (cursor.moveToNext()); + } + } + + return homeworks; + } + + @NotNull + public List getHomeworksBySubject(@NotNull String subject) { + String query = "SELECT * FROM " + DATABASE_NAME + + " WHERE " + COLUMN_NAME_SUBJECT + "=" + "?"; + List homeworks = new ArrayList<>(); + String[] selectionArgs = new String[]{String.valueOf(subject)}; + + try (SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery(query, selectionArgs)) { + if (cursor != null && cursor.moveToFirst()) { + do { + homeworks.add(getHomeworkByCursor(cursor)); + } while (cursor.moveToNext()); + } + } + + Collections.sort(homeworks, (h1, h2) -> h1.getDeadline().compareTo(h2.getDeadline())); + return homeworks; + } + + @NotNull + public List getPassedHomeworksBySubject(@NotNull String subject) { + List passedHomeworks = new ArrayList<>(); + for (Homework homework : getHomeworksBySubject(subject)) { + if (homework.hasPassed()) { + passedHomeworks.add(homework); + } + } + + return passedHomeworks; + } + + @NotNull + public List getHomeworksByDay(LocalDate date) { + String query = "SELECT * FROM " + DATABASE_NAME + " WHERE " + COLUMN_NAME_YEAR + "=? " + + "AND " + COLUMN_NAME_MONTH + "=? " + "AND " + COLUMN_NAME_DAY + "=?" + + "ORDER BY " + COLUMN_NAME_HOUR + ", " + COLUMN_NAME_MINUTE + " ASC"; + String[] selectionArgs = new String[]{String.valueOf(date.getYear()), + String.valueOf(date.getMonthOfYear()), String.valueOf(date.getDayOfMonth())}; + List homeworks = new ArrayList<>(); + + try (SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery(query, selectionArgs)) { + if (cursor != null && cursor.moveToFirst()) { + do { + Homework homework = getHomeworkByCursor(cursor); + homeworks.add(homework); + } while (cursor.moveToNext()); + } + } + + return homeworks; + } + + @NotNull + public List getHomeworksBetweenDates(int year1, int month1, int day1, + int year2, int month2, int day2) { + List homeworks = new ArrayList<>(); + try (SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery("SELECT * FROM " + DATABASE_NAME, null)) { + if (cursor != null && cursor.moveToFirst()) { + do { + Homework homework = getHomeworkByCursor(cursor); + if (homework.isBetween(year1, month1, day1, year2, month2, day2)) { + homeworks.add(homework); + } + } while (cursor.moveToNext()); + } + } + + return homeworks; + } + + public void deleteHomeworkById(int id) { + try (SQLiteDatabase database = this.getWritableDatabase()) { + database.delete(DATABASE_NAME, COLUMN_NAME_ID + " = ?", + new String[]{String.valueOf(id)}); + } + } + + public void setScoreById(int id, int score) { + try (SQLiteDatabase database = this.getWritableDatabase()) { + ContentValues values = new ContentValues(); + values.put(COLUMN_NAME_ACTUAL_SCORE, score); + database.update(DATABASE_NAME, values, COLUMN_NAME_ID + " = ?", + new String[]{String.valueOf(id)}); + } + } + + @NotNull + public List getHomeworkById(int id) { + String query = "SELECT * FROM " + DATABASE_NAME + " WHERE " + COLUMN_NAME_ID + "=?"; + String[] selectionArgs = new String[]{String.valueOf(id)}; + List homeworks = new ArrayList<>(); + + try (SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery(query, selectionArgs)) { + if (cursor != null && cursor.moveToFirst()) { + do { + Homework homework = getHomeworkByCursor(cursor); + homeworks.add(homework); + } while (cursor.moveToNext()); + } + } + + return homeworks; + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/ScheduleDatabaseController.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/ScheduleDatabaseController.java new file mode 100644 index 0000000..70092a2 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/ScheduleDatabaseController.java @@ -0,0 +1,114 @@ +package ru.spbau.group202.notdeadbydeadline.controller; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import ru.spbau.group202.notdeadbydeadline.model.ScheduleEntry; +import ru.spbau.group202.notdeadbydeadline.model.WeekParityEnum; + +public class ScheduleDatabaseController extends SQLiteOpenHelper { + private static final String DATABASE_NAME = "Schedule"; + private static final int DATABASE_VERSION = 1; + private static final String COLUMN_NAME_ID = "ID"; + private static final String COLUMN_NAME_SUBJECT = "SUBJECT"; + private static final String COLUMN_NAME_DAY_OF_WEEK = "DAY_OF_WEEK"; + private static final String COLUMN_NAME_HOUR = "HOUR"; + private static final String COLUMN_NAME_MINUTE = "MINUTE"; + private static final String COLUMN_NAME_WEEK_PARITY = "WEEK_PARITY"; + private static final String COLUMN_NAME_AUDITORIUM = "AUDITORIUM"; + private static final String COLUMN_NAME_TEACHER = "TEACHER"; + + public ScheduleDatabaseController(@NotNull Context context) { + super(context.getApplicationContext(), DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + Log.d("Database", "onCreate database"); + db.execSQL("CREATE TABLE " + DATABASE_NAME + " (" + + COLUMN_NAME_ID + " INTEGER PRIMARY KEY, " + + COLUMN_NAME_SUBJECT + " TEXT, " + + COLUMN_NAME_DAY_OF_WEEK + " INTEGER, " + + COLUMN_NAME_HOUR + " INTEGER, " + + COLUMN_NAME_MINUTE + " INTEGER, " + + COLUMN_NAME_WEEK_PARITY + " INTEGER, " + + COLUMN_NAME_AUDITORIUM + " TEXT, " + + COLUMN_NAME_TEACHER + " TEXT" + ");"); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldDATABASE_VERSION, int newDATABASE_VERSION) { + db.execSQL("DROP TABLE IF EXISTS " + DATABASE_NAME); + onCreate(db); + } + + @NotNull + private ScheduleEntry getScheduleEntryByCursor(@NotNull Cursor cursor) { + int id = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_ID)); + String subject = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_SUBJECT)); + int dayOfWeek = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_DAY_OF_WEEK)); + int hour = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_HOUR)); + int minute = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_MINUTE)); + int weekParity = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_WEEK_PARITY)); + String auditorium = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_AUDITORIUM)); + String teacher = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_TEACHER)); + + return new ScheduleEntry(subject, dayOfWeek, hour, minute, + WeekParityEnum.values()[weekParity], auditorium, teacher, id); + } + + public void addScheduleEntry(@NotNull ScheduleEntry scheduleEntry) { + try (SQLiteDatabase database = this.getWritableDatabase()) { + ContentValues values = new ContentValues(); + values.put(COLUMN_NAME_ID, scheduleEntry.getId()); + values.put(COLUMN_NAME_SUBJECT, scheduleEntry.getSubject()); + values.put(COLUMN_NAME_DAY_OF_WEEK, scheduleEntry.getDayOfWeek()); + values.put(COLUMN_NAME_HOUR, scheduleEntry.getHour()); + values.put(COLUMN_NAME_MINUTE, scheduleEntry.getMinute()); + values.put(COLUMN_NAME_WEEK_PARITY, scheduleEntry.getWeekParity().ordinal()); + values.put(COLUMN_NAME_AUDITORIUM, scheduleEntry.getAuditorium()); + values.put(COLUMN_NAME_TEACHER, scheduleEntry.getTeacher()); + long rowId = database.insert(DATABASE_NAME, null, values); + Log.d("Database", "inserted row number " + rowId); + } + } + + @NotNull + public List getDaySchedule(int dayOfWeek, WeekParityEnum weekParity) { + String query = "SELECT * FROM " + DATABASE_NAME + " WHERE " + COLUMN_NAME_DAY_OF_WEEK + "=? " + + "AND (" + COLUMN_NAME_WEEK_PARITY + "=? " + " OR " + COLUMN_NAME_WEEK_PARITY + "=?) " + + "ORDER BY " + COLUMN_NAME_HOUR + ", " + COLUMN_NAME_MINUTE; + + String[] selectionArgs = new String[]{String.valueOf(dayOfWeek), + String.valueOf(weekParity.ordinal()), String.valueOf(WeekParityEnum.ALWAYS.ordinal())}; + List daySchedule = new ArrayList<>(); + + try (SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery(query, selectionArgs)) { + if (cursor != null && cursor.moveToFirst()) { + do { + ScheduleEntry scheduleEntry = getScheduleEntryByCursor(cursor); + daySchedule.add(scheduleEntry); + } while (cursor.moveToNext()); + } + } + + return daySchedule; + } + + public void deleteScheduleEntryById(int id) { + try (SQLiteDatabase database = this.getWritableDatabase()) { + database.delete(DATABASE_NAME, COLUMN_NAME_ID + " = ?", + new String[]{String.valueOf(id)}); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/StoredDataController.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/StoredDataController.java new file mode 100644 index 0000000..05c8466 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/StoredDataController.java @@ -0,0 +1,74 @@ +package ru.spbau.group202.notdeadbydeadline.controller; + + +import android.content.Context; +import android.content.SharedPreferences; + +import org.jetbrains.annotations.NotNull; + +public class StoredDataController { + private static final String APP_PREFERENCES = "Settings"; + private static final String APP_PREFERENCES_INVERSE_WEEK_PARITY = "INVERSE_WEEK_PARITY"; + private static final String APP_PREFERENCES_TOTAL_NUMBER_OF_HW = "TOTAL_NUMBER_OF_HW"; + private static final String APP_PREFERENCES_TOTAL_NUMBER_OF_SCHEDULE_ENTRIES + = "TOTAL_NUMBER_OF_SCHEDULE_ENTRIES"; + private static final String APP_PREFERENCES_TOTAL_NUMBER_OF_EXAMS = "TOTAL_NUMBER_OF_EXAMS"; + private static final String APP_PREFERENCES_TOTAL_NUMBER_OF_STUDY_MATERIALS + = "TOTAL_NUMBER_OF_STUDY_MATERIALS"; + private SharedPreferences settings; + + public StoredDataController(@NotNull Context context) { + settings = context.getApplicationContext() + .getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE); + } + + public void saveWeekPairity(boolean isInversed) { + SharedPreferences.Editor editor = settings.edit(); + editor.putBoolean(APP_PREFERENCES_INVERSE_WEEK_PARITY, isInversed); + editor.apply(); + } + + public void saveTotalNumberOfHW(int totalNumberOfHW) { + SharedPreferences.Editor editor = settings.edit(); + editor.putInt(APP_PREFERENCES_TOTAL_NUMBER_OF_HW, totalNumberOfHW); + editor.apply(); + } + + public void saveTotalNumberOfScheduleEntries(int totalNumberOfScheduleEntries) { + SharedPreferences.Editor editor = settings.edit(); + editor.putInt(APP_PREFERENCES_TOTAL_NUMBER_OF_SCHEDULE_ENTRIES, totalNumberOfScheduleEntries); + editor.apply(); + } + + public void saveTotalNumberOfWorks(int totalNumberOfWorks) { + SharedPreferences.Editor editor = settings.edit(); + editor.putInt(APP_PREFERENCES_TOTAL_NUMBER_OF_EXAMS, totalNumberOfWorks); + editor.apply(); + } + + public void saveTotalNumberOfStudyMaterials(int totalNumberOfStudyMaterials) { + SharedPreferences.Editor editor = settings.edit(); + editor.putInt(APP_PREFERENCES_TOTAL_NUMBER_OF_STUDY_MATERIALS, totalNumberOfStudyMaterials); + editor.apply(); + } + + public boolean getParityOfWeek() { + return settings.getBoolean(APP_PREFERENCES_INVERSE_WEEK_PARITY, false); + } + + public int getTotalNumberOfHW() { + return settings.getInt(APP_PREFERENCES_TOTAL_NUMBER_OF_HW, 0); + } + + public int getTotalNumberOfScheduleEntries() { + return settings.getInt(APP_PREFERENCES_TOTAL_NUMBER_OF_SCHEDULE_ENTRIES, 0); + } + + public int getTotalNumberOfWorks() { + return settings.getInt(APP_PREFERENCES_TOTAL_NUMBER_OF_EXAMS, 0); + } + + public int getTotalNumberOfStudyMaterials() { + return settings.getInt(APP_PREFERENCES_TOTAL_NUMBER_OF_STUDY_MATERIALS, 0); + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/StudyMaterialDatabaseController.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/StudyMaterialDatabaseController.java new file mode 100644 index 0000000..3a2ee8c --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/StudyMaterialDatabaseController.java @@ -0,0 +1,135 @@ +package ru.spbau.group202.notdeadbydeadline.controller; + + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import ru.spbau.group202.notdeadbydeadline.model.StudyMaterial; + +public class StudyMaterialDatabaseController extends SQLiteOpenHelper { + private static final String DATABASE_NAME = "StudyMaterials"; + private static final int DATABASE_VERSION = 1; + private static final String COLUMN_NAME_ID = "ID"; + private static final String COLUMN_NAME_SUBJECT = "SUBJECT"; + private static final String COLUMN_NAME_TERM = "TERM"; + private static final String COLUMN_NAME_PATH = "PATH"; + private static final String COLUMN_NAME_URL = "URL"; + + public StudyMaterialDatabaseController(@NotNull Context context) { + super(context.getApplicationContext(), DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + Log.d("Database", "onCreate database"); + db.execSQL("CREATE TABLE " + DATABASE_NAME + " (" + + COLUMN_NAME_ID + " INTEGER PRIMARY KEY, " + + COLUMN_NAME_SUBJECT + " TEXT, " + + COLUMN_NAME_TERM + " INTEGER, " + + COLUMN_NAME_PATH + " TEXT, " + + COLUMN_NAME_URL + " TEXT" + ");"); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldDATABASE_VERSION, int newDATABASE_VERSION) { + db.execSQL("DROP TABLE IF EXISTS " + DATABASE_NAME); + onCreate(db); + } + + @NotNull + private StudyMaterial getStudyMaterialByCursor(@NotNull Cursor cursor) { + int id = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_ID)); + String subject = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_SUBJECT)); + int term = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_TERM)); + String path = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_PATH)); + String URL = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_URL)); + StudyMaterial studyMaterial = new StudyMaterial(subject, term, path, URL, id); + return studyMaterial; + } + + public void addStudyMaterial(@NotNull StudyMaterial studyMaterial) { + try (SQLiteDatabase database = this.getWritableDatabase()) { + ContentValues values = new ContentValues(); + values.put(COLUMN_NAME_ID, studyMaterial.getId()); + values.put(COLUMN_NAME_SUBJECT, studyMaterial.getSubject()); + values.put(COLUMN_NAME_TERM, studyMaterial.getTerm()); + values.put(COLUMN_NAME_PATH, studyMaterial.getPath()); + values.put(COLUMN_NAME_URL, studyMaterial.getURL()); + long rowId = database.insert(DATABASE_NAME, null, values); + Log.d("Database", "inserted row number " + rowId); + } + } + + @NotNull + public List getStudyMaterialsBySubject(@NotNull String subject) { + String query = "SELECT * FROM " + DATABASE_NAME + + " WHERE " + COLUMN_NAME_SUBJECT + "=" + "?"; + List studyMaterials = new ArrayList<>(); + String[] selectionArgs = new String[]{String.valueOf(subject)}; + + try (SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery(query, selectionArgs)) { + if (cursor != null && cursor.moveToFirst()) { + do { + studyMaterials.add(getStudyMaterialByCursor(cursor)); + } while (cursor.moveToNext()); + } + } + + return studyMaterials; + } + + @NotNull + public List getStudyMaterialsByTerm(int term) { + String query = "SELECT * FROM " + DATABASE_NAME + + " WHERE " + COLUMN_NAME_TERM + "=" + "?"; + List studyMaterials = new ArrayList<>(); + String[] selectionArgs = new String[]{String.valueOf(term)}; + + try (SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery(query, selectionArgs)) { + if (cursor != null && cursor.moveToFirst()) { + do { + studyMaterials.add(getStudyMaterialByCursor(cursor)); + } while (cursor.moveToNext()); + } + } + + return studyMaterials; + } + + public void deleteStudyMaterialById(int id) { + try (SQLiteDatabase database = this.getWritableDatabase()) { + database.delete(DATABASE_NAME, COLUMN_NAME_ID + " = ?", + new String[]{String.valueOf(id)}); + } + } + + @NotNull + public List getStudyMaterialById(int id) { + String query = "SELECT * FROM " + DATABASE_NAME + " WHERE " + COLUMN_NAME_ID + "=?"; + String[] selectionArgs = new String[]{String.valueOf(id)}; + List studyMaterials = new ArrayList<>(); + + try (SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery(query, selectionArgs)) { + if (cursor != null && cursor.moveToFirst()) { + do { + StudyMaterial studyMaterial = getStudyMaterialByCursor(cursor); + studyMaterials.add(studyMaterial); + } while (cursor.moveToNext()); + } + } + + return studyMaterials; + } +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/SubjectDatabaseController.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/SubjectDatabaseController.java new file mode 100644 index 0000000..5d88d07 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/SubjectDatabaseController.java @@ -0,0 +1,112 @@ +package ru.spbau.group202.notdeadbydeadline.controller; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import ru.spbau.group202.notdeadbydeadline.model.CreditByAcceptedHomeworks; +import ru.spbau.group202.notdeadbydeadline.model.CreditByPercent; +import ru.spbau.group202.notdeadbydeadline.model.CreditEnum; +import ru.spbau.group202.notdeadbydeadline.model.SubjectCredit; + + +public class SubjectDatabaseController extends SQLiteOpenHelper { + private static final String DATABASE_NAME = "Subjects"; + private static final int DATABASE_VERSION = 1; + private static final String COLUMN_NAME_SUBJECT = "SUBJECT"; + private static final String COLUMN_NAME_CREDIT_FORM = "CREDIT_FORM"; + private static final String COLUMN_NAME_PERCENT_FOR_CREDIT = "PERCENT_FOR_CREDIT"; + + public SubjectDatabaseController(@NotNull Context context) { + super(context.getApplicationContext(), DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + Log.d("Database", "onCreate database"); + db.execSQL("CREATE TABLE " + DATABASE_NAME + " (" + + COLUMN_NAME_SUBJECT + " TEXT PRIMARY KEY, " + + COLUMN_NAME_CREDIT_FORM + " INTEGER, " + + COLUMN_NAME_PERCENT_FOR_CREDIT + " REAL" + ");"); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldDATABASE_VERSION, int newDATABASE_VERSION) { + db.execSQL("DROP TABLE IF EXISTS " + DATABASE_NAME); + onCreate(db); + } + + public void addSubject(@NotNull String subject, @NotNull CreditEnum creditForm, double percentForCredit) { + try (SQLiteDatabase database = this.getWritableDatabase()) { + ContentValues values = new ContentValues(); + values.put(COLUMN_NAME_SUBJECT, subject); + values.put(COLUMN_NAME_CREDIT_FORM, creditForm.ordinal()); + values.put(COLUMN_NAME_PERCENT_FOR_CREDIT, percentForCredit); + long rowId = database.insert(DATABASE_NAME, null, values); + Log.d("Database", "inserted row number " + rowId); + } + } + + @NotNull + public List getAllSubjects() { + ArrayList subjects = new ArrayList<>(); + try (SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery("SELECT " + COLUMN_NAME_SUBJECT + + " FROM " + DATABASE_NAME, null)) { + if (cursor != null && cursor.moveToFirst()) { + do { + String subject = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_SUBJECT)); + subjects.add(subject); + } while (cursor.moveToNext()); + } + } + + return subjects; + } + + @NotNull + private SubjectCredit getSubjectCreditByCursor(@NotNull Cursor cursor) throws UnrecognizedCreditFormException { + String subject = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_SUBJECT)); + int creditForm = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_CREDIT_FORM)); + double percentForCredit = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME_PERCENT_FOR_CREDIT)); + + switch (CreditEnum.values()[creditForm]) { + case BY_PERCENT: + return new CreditByPercent(subject, percentForCredit); + case BY_ACCEPTED_HOMEWORKS: + return new CreditByAcceptedHomeworks(subject); + case NOT_STATED: + return new SubjectCredit(subject); + default: + throw new UnrecognizedCreditFormException(); + } + } + + @NotNull + public SubjectCredit getSubjectCredit(@NotNull String subject) throws UnrecognizedCreditFormException { + String query = "SELECT * FROM " + DATABASE_NAME + " WHERE " + COLUMN_NAME_SUBJECT + "=?"; + String[] selectionArgs = new String[]{subject}; + + try (SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery(query, selectionArgs)) { + return getSubjectCreditByCursor(cursor); + } + } + + public void setSubjectCreditForm(@NotNull String subject, @NotNull CreditEnum credit) { + try (SQLiteDatabase database = this.getWritableDatabase()) { + ContentValues values = new ContentValues(); + values.put(COLUMN_NAME_CREDIT_FORM, credit.ordinal()); + database.update(DATABASE_NAME, values, COLUMN_NAME_SUBJECT + " = ?", + new String[]{subject}); + } + } +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/UnrecognizedCreditFormException.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/UnrecognizedCreditFormException.java new file mode 100644 index 0000000..60c7d50 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/controller/UnrecognizedCreditFormException.java @@ -0,0 +1,5 @@ +package ru.spbau.group202.notdeadbydeadline.controller; + + +public class UnrecognizedCreditFormException extends Exception { +} \ No newline at end of file diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/CreditByAcceptedHomeworks.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/CreditByAcceptedHomeworks.java new file mode 100644 index 0000000..aee22aa --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/CreditByAcceptedHomeworks.java @@ -0,0 +1,35 @@ +package ru.spbau.group202.notdeadbydeadline.model; + + +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.List; + +public class CreditByAcceptedHomeworks extends SubjectCredit { + public CreditByAcceptedHomeworks(@NotNull String subject) { + super(subject); + } + + @NotNull + @Override + protected List calculateHomeworkProgress(@NotNull List homeworks) { + int numberOfCheckedHomeworks = 0; + int numberOfAcceptedHomeworks = 0; + + for (Homework homework : homeworks) { + if (homework.getActualScore() != -1 && homework.getExpectedScore() != -1) { + numberOfCheckedHomeworks++; + if (homework.isAccepted()) { + numberOfAcceptedHomeworks++; + } + } + } + double percent = numberOfCheckedHomeworks == 0 ? 1 : (double) numberOfAcceptedHomeworks / numberOfCheckedHomeworks; + String credit = percent == 1.0 ? "Passed class" : "Failed class"; + int numberOfNotAcceptedHomeworks = numberOfCheckedHomeworks - numberOfAcceptedHomeworks; + + return Arrays.asList("by accepted homeworks", Double.toString(percent), credit, + Integer.toString(numberOfNotAcceptedHomeworks)); + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/CreditByPercent.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/CreditByPercent.java new file mode 100644 index 0000000..d578094 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/CreditByPercent.java @@ -0,0 +1,36 @@ +package ru.spbau.group202.notdeadbydeadline.model; + + +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.List; + +public class CreditByPercent extends SubjectCredit { + private double percentForCredit; + + public CreditByPercent(@NotNull String subject, double percentForCredit) { + super(subject); + this.percentForCredit = percentForCredit; + } + + @NotNull + @Override + protected List calculateHomeworkProgress(@NotNull List homeworks) { + double totalPoints = 0; + double earnedPoints = 0; + + for (Homework homework : homeworks) { + if (homework.getActualScore() != -1 && homework.getExpectedScore() != -1) { + earnedPoints += homework.getActualScore(); + totalPoints += homework.getExpectedScore(); + } + } + + double percent = totalPoints == 0 ? 1 : earnedPoints / totalPoints; + String result = percent >= percentForCredit ? "Class passed" : "Class failed"; + double pointsForCredit = percentForCredit * totalPoints - earnedPoints; + return Arrays.asList("by percent", Double.toString(percent), result, + pointsForCredit < 0 ? "0" : Double.toString(pointsForCredit)); + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/CreditEnum.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/CreditEnum.java new file mode 100644 index 0000000..12e1c87 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/CreditEnum.java @@ -0,0 +1,6 @@ +package ru.spbau.group202.notdeadbydeadline.model; + + +public enum CreditEnum { + BY_ACCEPTED_HOMEWORKS, BY_PERCENT, NOT_STATED +} \ No newline at end of file diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/DetailedEntry.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/DetailedEntry.java new file mode 100644 index 0000000..67b83ba --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/DetailedEntry.java @@ -0,0 +1,11 @@ +package ru.spbau.group202.notdeadbydeadline.model; + + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; + +public interface DetailedEntry { + @NotNull + ArrayList getDetails(); +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/DetailedTimedEntry.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/DetailedTimedEntry.java new file mode 100644 index 0000000..a14b756 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/DetailedTimedEntry.java @@ -0,0 +1,14 @@ +package ru.spbau.group202.notdeadbydeadline.model; + +import org.jetbrains.annotations.NotNull; +import org.joda.time.LocalTime; + + +public abstract class DetailedTimedEntry implements DetailedEntry, Comparable { + @NotNull + protected abstract LocalTime getTime(); + + public int compareTo(@NotNull DetailedTimedEntry detailedEntry) { + return getTime().compareTo(detailedEntry.getTime()); + } +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/Exam.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/Exam.java new file mode 100644 index 0000000..e3d7e48 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/Exam.java @@ -0,0 +1,96 @@ +package ru.spbau.group202.notdeadbydeadline.model; + + +import org.jetbrains.annotations.NotNull; +import org.joda.time.LocalDateTime; +import org.joda.time.LocalTime; +import org.joda.time.format.DateTimeFormat; + +import java.util.ArrayList; + + +public class Exam extends DetailedTimedEntry { + private String subject, description; + private LocalDateTime date; + private boolean isAccepted = false; + private ExamEnum examType; + private int id; + + public Exam(@NotNull String subject, String description, @NotNull LocalDateTime date, + @NotNull ExamEnum examType, int id) { + this.subject = subject; + this.description = description; + this.date = date; + this.examType = examType; + this.id = id; + } + + public boolean isAccepted() { + return isAccepted; + } + + public void setAccepted(boolean isAccepted) { + this.isAccepted = isAccepted; + } + + @NotNull + public String getSubject() { + return subject; + } + + public String getDescription() { + return description; + } + + public int getYear() { + return date.getYear(); + } + + public int getMonth() { + return date.getMonthOfYear(); + } + + public int getDay() { + return date.getDayOfMonth(); + } + + public int getHour() { + return date.getHourOfDay(); + } + + public int getMinute() { + return date.getMinuteOfHour(); + } + + @NotNull + public ExamEnum getExamType() { + return examType; + } + + public int getId() { + return id; + } + + @Override + @NotNull + public ArrayList getDetails() { + ArrayList workDetails = new ArrayList<>(); + workDetails.add(subject); + workDetails.add(DateTimeFormat.forPattern("HH:mm").print(date)); + workDetails.add(examType.getDescription()); + workDetails.add(description); + workDetails.add(Integer.toString(id)); + return workDetails; + } + + @NotNull + @Override + protected LocalTime getTime() { + return date.toLocalTime(); + } + + public boolean hasPassed() { + return LocalDateTime.now().compareTo(date) > 0; + } + +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/ExamEnum.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/ExamEnum.java new file mode 100644 index 0000000..c463722 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/ExamEnum.java @@ -0,0 +1,17 @@ +package ru.spbau.group202.notdeadbydeadline.model; + + +public enum ExamEnum { + TEST() { + public String getDescription() { + return "Test"; + } + }, + FINAL_EXAM() { + public String getDescription() { + return "Exam"; + } + }; + + public abstract String getDescription(); +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/Homework.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/Homework.java new file mode 100644 index 0000000..560e5da --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/Homework.java @@ -0,0 +1,170 @@ +package ru.spbau.group202.notdeadbydeadline.model; + +import java.util.ArrayList; + +import org.jetbrains.annotations.NotNull; +import org.joda.time.LocalDate; +import org.joda.time.LocalDateTime; +import org.joda.time.LocalTime; +import org.joda.time.format.*; + +public class Homework extends DetailedTimedEntry { + private Deadline deadline; + private String subject, description, howToSend; + private int regularity; + private double expectedScore, actualScore = -1; + private int id; + private ArrayList materials; + + public Homework(LocalDateTime deadline, @NotNull String subject, int regularity, String description, + String howToSend, double expectedScore, int id, @NotNull ArrayList materials) { + this.deadline = new Deadline(deadline); + this.subject = subject; + this.regularity = regularity; + this.description = description; + this.howToSend = howToSend; + this.expectedScore = expectedScore; + this.id = id; + this.materials = materials; + } + + public void setActualScore(double score) { + actualScore = score; + } + + public boolean isAccepted() { + return actualScore >= expectedScore; + } + + @NotNull + public ArrayList getDetails() { + ArrayList homeworkDetails = new ArrayList<>(); + homeworkDetails.add(getDescription()); + homeworkDetails.add(deadline.getFormattedDeadline()); + homeworkDetails.add(getHowToSend()); + if (getExpectedScore() == -1.0) { + homeworkDetails.add("Not specified"); + } else { + homeworkDetails.add(Double.toString(getExpectedScore())); + } + homeworkDetails.addAll(materials); + homeworkDetails.add(Integer.toString(id)); + + return homeworkDetails; + } + + @NotNull + @Override + protected LocalTime getTime() { + return deadline.deadline.toLocalTime(); + } + + public Deadline getDeadline() { + return deadline; + } + + @NotNull + public String getSubject() { + return subject; + } + + public String getDescription() { + return description; + } + + public int getRegularity() { + return regularity; + } + + public String getHowToSend() { + return howToSend; + } + + public double getExpectedScore() { + return expectedScore; + } + + public double getActualScore() { + return actualScore; + } + + public int getYear() { + return deadline.deadline.getYear(); + } + + public int getMonth() { + return deadline.deadline.getMonthOfYear(); + } + + public int getDay() { + return deadline.deadline.getDayOfMonth(); + } + + public int getHour() { + return deadline.deadline.getHourOfDay(); + } + + public int getMinute() { + return deadline.deadline.getMinuteOfHour(); + } + + public boolean hasPassed() { + return deadline.hasPassed(); + } + + public boolean isBetween(int year1, int month1, int day1, + int year2, int month2, int day2) { + return (new LocalDate(year1, month1, day1)).isAfter(deadline.deadline.toLocalDate()) && + (new LocalDate(year2, month2, day2)).isBefore(deadline.deadline.toLocalDate()); + } + + public int getId() { + return id; + } + + public ArrayList getMaterials() { + return materials; + } + + @NotNull + public Homework generateNewHomeworkById(int id) { + LocalDateTime newDeadline = deadline.deadline.plusWeeks(regularity); + return new Homework(newDeadline, subject, regularity, " ", howToSend, + -1, id, new ArrayList<>()); + } + + public class Deadline extends DetailedTimedEntry { + private LocalDateTime deadline; + + private Deadline(@NotNull LocalDateTime deadline) { + this.deadline = deadline; + } + + private boolean hasPassed() { + return LocalDateTime.now().compareTo(deadline) > 0; + } + + @NotNull + private String getFormattedDeadline() { + DateTimeFormatter formatter = DateTimeFormat.forPattern("dd.MM.yyyy HH:mm"); + return formatter.print(deadline); + } + + @NotNull + public ArrayList getDetails() { + ArrayList deadlineDetails = new ArrayList<>(); + deadlineDetails.add(getSubject()); + deadlineDetails.add(getDescription()); + deadlineDetails.add(getFormattedDeadline()); + + return deadlineDetails; + } + + @NotNull + @Override + protected LocalTime getTime() { + return deadline.toLocalTime(); + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/ScheduleEntry.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/ScheduleEntry.java new file mode 100644 index 0000000..21e079c --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/ScheduleEntry.java @@ -0,0 +1,75 @@ +package ru.spbau.group202.notdeadbydeadline.model; + +import org.jetbrains.annotations.NotNull; +import org.joda.time.LocalTime; +import org.joda.time.format.DateTimeFormat; + +import java.util.ArrayList; + +public class ScheduleEntry extends DetailedTimedEntry { + private String subject, auditorium, teacher; + private LocalTime time; + private int dayOfWeek, id; + private WeekParityEnum weekParity; + + public ScheduleEntry(@NotNull String subject, int dayOfWeek, int hour, int minute, + WeekParityEnum weekParity, String auditorium, String teacher, int id) { + time = new LocalTime(hour, minute); + this.subject = subject; + this.dayOfWeek = dayOfWeek; + this.weekParity = weekParity; + this.auditorium = auditorium; + this.teacher = teacher; + this.id = id; + } + + @NotNull + public ArrayList getDetails() { + ArrayList classDetails = new ArrayList<>(); + classDetails.add(subject); + classDetails.add(DateTimeFormat.forPattern("HH:mm").print(time)); + classDetails.add(teacher); + classDetails.add(auditorium); + classDetails.add(Integer.toString(id)); + return classDetails; + } + + @NotNull + @Override + protected LocalTime getTime() { + return time; + } + + public int getHour() { + return time.getHourOfDay(); + } + + public int getMinute() { + return time.getMinuteOfHour(); + } + + @NotNull + public String getSubject() { + return subject; + } + + public String getAuditorium() { + return auditorium; + } + + public String getTeacher() { + return teacher; + } + + public int getDayOfWeek() { + return dayOfWeek; + } + + public WeekParityEnum getWeekParity() { + return weekParity; + } + + public int getId() { + return id; + } +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/StudyMaterial.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/StudyMaterial.java new file mode 100644 index 0000000..7209f9e --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/StudyMaterial.java @@ -0,0 +1,62 @@ +package ru.spbau.group202.notdeadbydeadline.model; + + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; + +public class StudyMaterial implements DetailedEntry { + private String subject = "Not stated", path, URL; + private int term, id; + + public StudyMaterial(@NotNull String subject, int term, @NotNull String URL, + @NotNull String path, int id) { + this.subject = subject; + this.term = term; + this.URL = URL; + this.path = path; + this.id = id; + update(); + } + + @NotNull + public String getPath() { + return path; + } + + @NotNull + public String getURL() { + return URL; + } + + public int getTerm() { + return term; + } + + @NotNull + public String getSubject() { + return subject; + } + + public int getId() { + return id; + } + + //TODO + public void update() { + + } + + @NotNull + @Override + public ArrayList getDetails() { + ArrayList studyMaterialDetails = new ArrayList<>(); + studyMaterialDetails.add(subject); + studyMaterialDetails.add(Integer.toString(term)); + studyMaterialDetails.add(path); + studyMaterialDetails.add(URL); + studyMaterialDetails.add(Integer.toString(id)); + + return studyMaterialDetails; + } +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/SubjectCredit.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/SubjectCredit.java new file mode 100644 index 0000000..9d1bca1 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/SubjectCredit.java @@ -0,0 +1,60 @@ +package ru.spbau.group202.notdeadbydeadline.model; + +import org.jetbrains.annotations.NotNull; +import org.apache.commons.collections4.ListUtils; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +public class SubjectCredit { + private String subject; + + public SubjectCredit(@NotNull String subject) { + this.subject = subject; + } + + @NotNull + public List calculateProgress(@NotNull List homeworks, @NotNull List exams) { + HashMap totalNumber = new HashMap<>(); + HashMap numberOfPassed = new HashMap<>(); + + for (Exam exam : exams) { + ExamEnum kind = exam.getExamType(); + totalNumber.put(kind, totalNumber.get(kind) + 1); + if (exam.isAccepted()) { + numberOfPassed.put(kind, numberOfPassed.get(kind) + 1); + } + } + + double passedTestsPercent = totalNumber.get(ExamEnum.TEST) == 0 ? 1 : + (double) numberOfPassed.get(ExamEnum.TEST) / totalNumber.get(ExamEnum.TEST); + double passedExamsPercent = totalNumber.get(ExamEnum.FINAL_EXAM) == 0 ? 1 : + (double) numberOfPassed.get(ExamEnum.FINAL_EXAM) / totalNumber.get(ExamEnum.FINAL_EXAM); + String testCredit = passedTestsPercent == 1.0 ? "Passed class" : "Failed class"; + String examsCredit = passedExamsPercent == 1.0 ? "Passed class" : "Failed class"; + int numberOfNotPassedTests = totalNumber.get(ExamEnum.TEST) - numberOfPassed.get(ExamEnum.TEST); + int numberOfNotPassedExams = totalNumber.get(ExamEnum.FINAL_EXAM) - numberOfPassed.get(ExamEnum.FINAL_EXAM); + + List result = Arrays.asList(Double.toString(passedTestsPercent), testCredit, + Integer.toString(numberOfNotPassedTests), Double.toString(passedExamsPercent), examsCredit, + Integer.toString(numberOfNotPassedExams)); + return ListUtils.union(calculateHomeworkProgress(homeworks), result); + } + + @NotNull + protected List calculateHomeworkProgress(@NotNull List homeworks) { + double totalPoints = 0; + double earnedPoints = 0; + + for (Homework homework : homeworks) { + if (homework.getActualScore() != -1) { + earnedPoints += homework.getActualScore(); + totalPoints += homework.getExpectedScore(); + } + } + + double percent = totalPoints == 0 ? 1 : earnedPoints / totalPoints; + return Arrays.asList("not stated", Double.toString(percent)); + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/WeekParityEnum.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/WeekParityEnum.java new file mode 100644 index 0000000..0eda574 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/model/WeekParityEnum.java @@ -0,0 +1,22 @@ +package ru.spbau.group202.notdeadbydeadline.model; + + +public enum WeekParityEnum { + ON_EVEN_WEEK() { + public WeekParityEnum inverse() { + return ON_ODD_WEEK; + } + }, + ON_ODD_WEEK() { + public WeekParityEnum inverse() { + return ON_EVEN_WEEK; + } + }, + ALWAYS() { + public WeekParityEnum inverse() { + return ALWAYS; + } + }; + + public abstract WeekParityEnum inverse(); +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/AddHomeworkActivity.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/AddHomeworkActivity.java new file mode 100644 index 0000000..d1cc24a --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/AddHomeworkActivity.java @@ -0,0 +1,415 @@ +package ru.spbau.group202.notdeadbydeadline.ui; + +import android.content.Context; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; +import android.widget.Button; +import android.widget.DatePicker; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.TimePicker; +import android.widget.Toast; + +import org.joda.time.LocalDateTime; + +import java.util.ArrayList; +import java.util.List; + +import ru.spbau.group202.notdeadbydeadline.controller.Controller; +import ru.spbau.group202.notdeadbydeadline.R; +import ru.spbau.group202.notdeadbydeadline.ui.utilities.AbstractDatePicker; +import ru.spbau.group202.notdeadbydeadline.ui.utilities.AbstractTimePicker; + +public class AddHomeworkActivity extends AppCompatActivity { + + private static final String TAG = "AddHomeworkActivity"; + public static final HomeworkFieldsAccumulator HFA = new HomeworkFieldsAccumulator(); + private static boolean isSetTime = false; + private static boolean isSetDate = false; + private static boolean isSetSubject = false; + private static boolean isSetDescription = false; + private static boolean isSetExpectedScore = false; + private static boolean isSetHowToSend = false; + + private static List homeworkEntry = new ArrayList<>(); + + private int id = -1; + + public void processSubject() { + + final List source = Controller.getSubjectList(); + + final AutoCompleteTextView actv = findViewById(R.id.getSubjectACTV); + actv.setAdapter(new ArrayAdapter<>(this, + android.R.layout.simple_dropdown_item_1line, source)); + + + HFA.storeSubject(actv.getText().toString()); + + if (id != -1 && !isSetSubject) { + actv.setText(homeworkEntry.get(0)); + } + + actv.setOnEditorActionListener(new TextView.OnEditorActionListener() { + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (!source.contains(actv.getText().toString())) { + source.add(actv.getText().toString()); + } + HFA.storeSubject((actv.getText().toString())); + + + if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) + || (actionId == EditorInfo.IME_ACTION_DONE)) { + Log.e("TAG", "Done pressed"); + } + return false; + } + }); + + actv.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //HFA.storeSubject((actv.getText().toString())); + if (!source.contains(actv.getText().toString())) { + source.add(actv.getText().toString()); + } + + View view1 = getCurrentFocus(); + if (view1 != null) { + InputMethodManager inputManager = + (InputMethodManager) getSystemService( + Context.INPUT_METHOD_SERVICE); + + if (inputManager != null) { + inputManager.hideSoftInputFromWindow(view1.getWindowToken(), + InputMethodManager.HIDE_NOT_ALWAYS); + } + + } + } + }); + } + + public void getSubject() { + final AutoCompleteTextView actv = findViewById(R.id.getSubjectACTV); + + HFA.storeSubject(actv.getText().toString()); + } + + public void getDescription() { + final EditText editText = findViewById(R.id.getDescriptionEditText); + + HFA.storeDescription(editText.getText().toString()); + + if (id != -1 && !isSetDescription) { + editText.setText(homeworkEntry.get(1)); + } + } + + public void getExpectedScore() { + final EditText editText = findViewById(R.id.expectedScore); + + if (id != -1 && !isSetExpectedScore) { + editText.setText(homeworkEntry.get(4)); + } + + String expectedScore = editText.getText().toString(); + if (!expectedScore.equals("") && isParseableDouble(expectedScore)) { + HFA.storeExpectedScore(Double.parseDouble(expectedScore)); + } else { + HFA.storeExpectedScore(-1.0); + } + } + + public void processHowToSend() { + final EditText editText = findViewById(R.id.submitWayEditText); + + editText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) + || (actionId == EditorInfo.IME_ACTION_DONE)) { + Log.d(TAG, "Done pressed"); + } + return false; + } + }); + + editText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + HFA.storeHowToSend(editText.getText().toString()); + + + View view1 = getCurrentFocus(); + if (view1 != null) { + InputMethodManager inputManager = + (InputMethodManager) getSystemService( + Context.INPUT_METHOD_SERVICE); + if (inputManager != null) { + inputManager.hideSoftInputFromWindow(view1.getWindowToken(), + InputMethodManager.HIDE_NOT_ALWAYS); + } + } + return false; + } + }); + + + if (id != -1 && !isSetHowToSend) { + editText.setText(homeworkEntry.get(3)); + } + } + + public void getHowToSend() { + final EditText editText = findViewById(R.id.submitWayEditText); + + HFA.storeHowToSend(editText.getText().toString()); + } + + public void setTime(View view) { + TimePickerFragment timePickerFragment = new TimePickerFragment(); + if (id != -1 && !isSetTime) { + String[] date = homeworkEntry.get(2).split("[\\s:.]+"); + timePickerFragment.setValues(Integer.parseInt(date[3]), + Integer.parseInt(date[4])); + } + + timePickerFragment.show(getSupportFragmentManager(), "timePicker"); + } + + public void setDate(View view) { + DatePickerFragment datePickerFragment = new DatePickerFragment(); + if (id != -1 && !isSetDate) { + String[] date = homeworkEntry.get(2).split("[\\s:.]+"); + datePickerFragment.setValues(Integer.parseInt(date[2]), + Integer.parseInt(date[1]) - 1, + Integer.parseInt(date[0])); + } + + datePickerFragment.show(getSupportFragmentManager(), "datePicker"); + } + + /*public void getRegularity() { + CheckBox checkBox = findViewById(R.id.isRegularCheckBox); + + }*/ + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_add_homework); + + id = getIntent().getIntExtra("id", -1); + + if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + if (id != -1) { + TextView header = findViewById(R.id.addNewHWHeader); + header.setText(getResources().getString(R.string.edit_hw_entry)); + homeworkEntry = Controller.HomeworkController.getHomeworkById(id); + } + + processSubject(); + getDescription(); + getExpectedScore(); + processHowToSend(); + + Button addHomeworkButton = findViewById(R.id.finishButton); + addHomeworkButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + getDescription(); + processSubject(); + getSubject(); + getExpectedScore(); + getHowToSend(); + + if (id == -1 && !HFA.isValidForAdding()) { + Toast.makeText(getApplicationContext(), + "Fill 'subject' and input correct date", + Toast.LENGTH_LONG).show(); + } else if (id != -1 && !HFA.isValidForEditing()) { + Toast.makeText(getApplicationContext(), + "Fill 'subject'", + Toast.LENGTH_LONG).show(); + } else { + if (id == -1) { + HFA.addNewHomework(); + } else { + HFA.editHomework(id); + } + HFA.clear(); + finish(); + } + } + }); + } + + private boolean isParseableDouble(String string) { + try { + Double.parseDouble(string); + return true; + } catch(NumberFormatException e) { + return false; + } + } + + public static class HomeworkFieldsAccumulator { + private String subject; + private String description; + private int year; + private int month; + private int day; + private int hour; + private int minutes; + private double expectedScore; + private boolean isRegular; + private String howToSend; + + public void storeSubject(String subject) { + if (this.subject != null && !this.subject.equals(subject)) { + isSetSubject = true; + } + this.subject = subject == null ? "" : subject; + } + + public void storeDescription(String description) { + if (this.description != null && !this.description.equals(description)) { + isSetDescription = true; + } + this.description = description == null ? "" : description; + } + + public void storeExpectedScore(double expectedScore) { + if (this.expectedScore != expectedScore) { //expectedScore != -1.0 && + isSetExpectedScore = true; + } + this.expectedScore = expectedScore; + } + + public void storeDate(int year, int month, int day) { + this.year = year; + this.month = month; + this.day = day; + } + + public void storeTime(int hour, int minutes) { + this.hour = hour; + this.minutes = minutes; + } + + /*public void storeRegularity(boolean isRegular) { + this.isRegular = isRegular; + }*/ + + public void storeHowToSend(String howToSend) { + if (this.howToSend != null && !this.howToSend.equals(howToSend)) { + isSetHowToSend = true; + } + this.howToSend = howToSend == null ? "" : howToSend; + } + + public void addNewHomework() { + + if (description == null) { + description = " "; + } + + if (howToSend == null) { + howToSend = " "; + } + + // TODO add lists + Controller.HomeworkController.addHomework(new LocalDateTime(year, month, day, hour, minutes), + subject, 0, description, + howToSend, expectedScore, new ArrayList<>()); + } + + public void editHomework( int id ) { + if (description == null) { + description = " "; + } + + if (howToSend == null) { + howToSend = " "; + } + + if (!isSetDate) { + String[] date = AddHomeworkActivity.homeworkEntry.get(2).split("[\\s:.]+"); + year = Integer.parseInt(date[2]); + month = Integer.parseInt(date[1]); + day = Integer.parseInt(date[0]); + } + + if (!isSetTime) { + String[] date = AddHomeworkActivity.homeworkEntry.get(2).split("[\\s:.]+"); + hour = Integer.parseInt(date[3]); + minutes = Integer.parseInt(date[4]); + } + + Controller.HomeworkController.editHomeworkById(id, new LocalDateTime(year, month, day, hour, minutes), + subject, 0, description, + howToSend, expectedScore, new ArrayList<>()); + + } + + public boolean isValidForAdding() { + return subject != null && isSetDate && isSetTime; + } + + public boolean isValidForEditing() { + return subject.trim().length() > 0; + } + + public void clear() { + subject = null; + description = null; + howToSend = null; + expectedScore = 0; + year = 0; + month= 0; + day = 0; + hour = 0; + minutes = 0; + + isSetTime = false; + isSetDate = false; + isSetExpectedScore = false; + isSetSubject = false; + isSetDescription = false; + isSetHowToSend = false; + } + + } + + public static class TimePickerFragment extends AbstractTimePicker { + + @Override + public void onTimeSet(TimePicker view, int hourOfDay, int minute) { + isSetTime = true; + HFA.storeTime(hourOfDay, minute); + } + + } + + public static class DatePickerFragment extends AbstractDatePicker { + @Override + public void onDateSet(DatePicker view, int year, int month, int day) { + isSetDate = true; + HFA.storeDate(year, month + 1, day); + } + } + + +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/AddScheduleEntryActivity.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/AddScheduleEntryActivity.java new file mode 100644 index 0000000..be11c34 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/AddScheduleEntryActivity.java @@ -0,0 +1,255 @@ +package ru.spbau.group202.notdeadbydeadline.ui; + +import android.content.Context; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.PopupMenu; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.KeyEvent; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.TimePicker; +import android.widget.Toast; + +import ru.spbau.group202.notdeadbydeadline.R; +import ru.spbau.group202.notdeadbydeadline.controller.Controller; +import ru.spbau.group202.notdeadbydeadline.model.ScheduleEntry; +import ru.spbau.group202.notdeadbydeadline.model.WeekParityEnum; +import ru.spbau.group202.notdeadbydeadline.ui.utilities.AbstractTimePicker; +import ru.spbau.group202.notdeadbydeadline.ui.utilities.WeekDayEnum; + +public class AddScheduleEntryActivity extends AppCompatActivity { + + private static final String TAG = "AddSchEntryActivity"; + private static final ScheduleEntryFieldsAccumulator SEFA = new ScheduleEntryFieldsAccumulator(); + private static boolean isSetTime = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_add_schedule_entry); + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setTitle("Add a new schedule entry"); + } + + getSubject(); + getAuditorium(); + getTeacher(); + getParity(); + + Button addSEbutton = findViewById(R.id.scheduleFinishButton); + addSEbutton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + getSubject(); + getAuditorium(); + getTeacher(); + getParity(); + + if (SEFA.isValidSE()) { + SEFA.addScheduleEntry(); + SEFA.clear(); + finish(); + } else { + Toast.makeText(getApplicationContext(), + "Fill all fields", Toast.LENGTH_LONG).show(); + } + } + }); + + } + + public void setWeekDay(View view) { + Button button = findViewById(R.id.scheduleSetWeekDayButton); + PopupMenu popup = new PopupMenu(AddScheduleEntryActivity.this, button); + popup.getMenuInflater() + .inflate(R.menu.week_day_menu, popup.getMenu()); + //registering popup with OnMenuItemClickListener + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + SEFA.storeWeekDay(item.getTitle().toString());// item.getTitle() + return true; + } + }); + + popup.show(); //showing popup menu + } + + public void scheduleSetTime(View view) { + TimePickerFragment timePickerFragment = new TimePickerFragment(); + + timePickerFragment.show(getSupportFragmentManager(), "timePicker"); + } + + public void getSubject() { + EditText editText = findViewById(R.id.scheduleGetSubjectET); + + editText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + SEFA.storeSubject((editText.getText().toString())); + + + if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) + || (actionId == EditorInfo.IME_ACTION_DONE)) { + Log.e("TAG", "Done pressed"); + } + return false; + } + }); + + SEFA.storeSubject(editText.getText().toString()); + } + + public void getTeacher() { + EditText editText = findViewById(R.id.scheduleTeacherET); + + editText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + SEFA.storeTeacher((editText.getText().toString())); + + + if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) + || (actionId == EditorInfo.IME_ACTION_DONE)) { + Log.e("TAG", "Done pressed"); + } + return false; + } + }); + + SEFA.storeTeacher(editText.getText().toString()); + } + + public void getAuditorium() { + EditText editText = findViewById(R.id.scheduleAuditoriumET); + + editText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + SEFA.storeAuditorium((editText.getText().toString())); + + + if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) + || (actionId == EditorInfo.IME_ACTION_DONE)) { + Log.e("TAG", "Done pressed"); + } + return false; + } + }); + + SEFA.storeAuditorium(editText.getText().toString()); + } + + public void getParity() { + String parity[] = {"even weeks", "odd weeks", "every week"}; + ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, parity); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + + Spinner spinner = findViewById(R.id.weekParitySpinner); + spinner.setAdapter(adapter); + spinner.setPrompt("Week Parity"); + spinner.setSelection(2); + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, + int position, long id) { + String text = parent.getItemAtPosition(position).toString(); + switch (text) { + case "even weeks": + SEFA.storeParity(WeekParityEnum.ON_EVEN_WEEK); + break; + case "odd weeks": + SEFA.storeParity(WeekParityEnum.ON_ODD_WEEK); + break; + case "every week": + SEFA.storeParity(WeekParityEnum.ALWAYS); + break; + default: + Log.e(TAG,"wrong week parity type"); + } + } + @Override + public void onNothingSelected(AdapterView arg0) { + } + }); + } + + + public static class ScheduleEntryFieldsAccumulator{ + private String subject = null; + private String teacher = null; + private String auditorium = null; + private String weekDay = null; + private WeekParityEnum parity; + private int hour; + private int minute; + + public void storeWeekDay(String weekDay) { + this.weekDay = weekDay; + } + + public void storeSubject(String subject) { + this.subject = subject; + } + + public void storeAuditorium(String auditorium) { + this.auditorium = auditorium; + } + + public void storeTeacher(String teacher) { + this.teacher = teacher; + } + + public void storeTime(int hour, int minute) { + this.hour = hour; + this.minute = minute; + } + + public void storeParity(WeekParityEnum parity) { + this.parity = parity; + } + + public boolean isValidSE() { + return subject != null && teacher != null && auditorium != null + && weekDay != null && isSetTime; + } + + public void addScheduleEntry() { + Controller.ScheduleController.addScheduleEntry(subject, + WeekDayEnum.valueOf(weekDay).ordinal(), hour, minute, + parity, auditorium, teacher); + } + + public void clear() { + subject = null; + teacher = null; + auditorium = null; + weekDay = null; + hour = 0; + minute = 0; + } + + } + + public static class TimePickerFragment extends AbstractTimePicker { + @Override + public void onTimeSet(TimePicker view, int hourOfDay, int minute) { + isSetTime = true; + SEFA.storeTime(hourOfDay, minute); + } + } + +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/DeadlinesActivity.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/DeadlinesActivity.java new file mode 100644 index 0000000..6868638 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/DeadlinesActivity.java @@ -0,0 +1,282 @@ +package ru.spbau.group202.notdeadbydeadline.ui; + +import android.content.Intent; +import android.graphics.Typeface; +import android.os.Bundle; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.style.StyleSpan; +import android.support.design.widget.NavigationView; +import android.support.v4.view.GravityCompat; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.app.ActionBarDrawerToggle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.ListView; +import android.widget.TableLayout; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; + +import org.jetbrains.annotations.NotNull; + +import org.joda.time.LocalDate; +import org.joda.time.DateTimeConstants; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; + +import ru.spbau.group202.notdeadbydeadline.controller.Controller; +import ru.spbau.group202.notdeadbydeadline.R; +import ru.spbau.group202.notdeadbydeadline.ui.utilities.ListViewUtility; + +public class DeadlinesActivity extends AppCompatActivity + implements NavigationView.OnNavigationItemSelectedListener { + + private static final String TAG = "DeadlinesActivity"; + + private LocalDate localDate; + + private void outputDeadlineByDay( int dayNumber ) { + + List> deadlinesDetails; + + LocalDate weekDay = localDate.withDayOfWeek(dayNumber); + deadlinesDetails = Controller.HomeworkController + .getDeadlinesByDay(weekDay); + + ArrayList formattedDeadlines = new ArrayList<>(); + for (List deadlineDetails : deadlinesDetails) { + SpannableStringBuilder stringBuilder = + new SpannableStringBuilder(deadlineDetails.get(2) + .split("\\s+")[1]); + + + int position = stringBuilder.length(); + stringBuilder.append(" "); + stringBuilder.append(deadlineDetails.get(0)); + stringBuilder.setSpan(new StyleSpan(Typeface.BOLD), + position, stringBuilder.length(), + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + stringBuilder.append("\n"); + stringBuilder.append(deadlineDetails.get(1)); + + formattedDeadlines.add(stringBuilder); + } + + ListView lv; + switch (dayNumber) { + case DateTimeConstants.MONDAY: + lv = findViewById(R.id.deadlinesMondayList); + break; + case DateTimeConstants.TUESDAY: + lv = findViewById(R.id.deadlinesTuesdayList); + break; + case DateTimeConstants.WEDNESDAY: + lv = findViewById(R.id.deadlinesWednesdayList); + break; + case DateTimeConstants.THURSDAY: + lv = findViewById(R.id.deadlinesThursdayList); + break; + case DateTimeConstants.FRIDAY: + lv = findViewById(R.id.deadlinesFridayList); + break; + case DateTimeConstants.SATURDAY: + lv = findViewById(R.id.deadlinesSaturdayList); + break; + case DateTimeConstants.SUNDAY: + lv = findViewById(R.id.deadlinesSundayList); + break; + default: + Log.e(TAG, "Wrong dayNumber parameter in OutputDeadlineByDay"); + return; + } + + ArrayAdapter adapter = new ArrayAdapter<>(this, + R.layout.custom_deadline_listview_entry, + formattedDeadlines); + lv.setAdapter(adapter); + } + + private void setListViewsHeightAllDays() { + ListView monday = findViewById(R.id.deadlinesMondayList); + ListView tuesday = findViewById(R.id.deadlinesTuesdayList); + ListView wednesday = findViewById(R.id.deadlinesWednesdayList); + ListView thursday = findViewById(R.id.deadlinesThursdayList); + ListView friday = findViewById(R.id.deadlinesFridayList); + ListView saturday = findViewById(R.id.deadlinesSaturdayList); + + ListViewUtility.setTwoListViewsHeight(monday, thursday); + ListViewUtility.setTwoListViewsHeight(tuesday, friday); + ListViewUtility.setTwoListViewsHeight(wednesday, saturday); + } + + private void outputDeadlines() { + + final TableLayout table = findViewById(R.id.deadlinesTableLayout); + table.setColumnShrinkable(0, true); + table.setColumnShrinkable(1, true); + + for (int i = 1; i <= 7; ++i) + outputDeadlineByDay(i); + + setListViewsHeightAllDays(); + } + + private void setHeaders() { + + DateTimeFormatter formatter = DateTimeFormat.forPattern("dd.MM.yyyy"); + + String monday = getResources().getString(R.string.monday_for_deadlines, + formatter.print(localDate.withDayOfWeek(1))); + String tuesday = getResources().getString(R.string.tuesday_for_deadlines, + formatter.print(localDate.withDayOfWeek(2))); + String wednesday = getResources().getString(R.string.wednesday_for_deadlines, + formatter.print(localDate.withDayOfWeek(3))); + String thursday = getResources().getString(R.string.thursday_for_deadlines, + formatter.print(localDate.withDayOfWeek(4))); + String friday = getResources().getString(R.string.friday_for_deadlines, + formatter.print(localDate.withDayOfWeek(5))); + String saturday = getResources().getString(R.string.saturday_for_deadlines, + formatter.print(localDate.withDayOfWeek(6))); + String sunday = getResources().getString(R.string.sunday_for_deadlines, + formatter.print(localDate.withDayOfWeek(7))); + + TextView tv = findViewById(R.id.deadlinesMondayHeader); + tv.setText(monday); + tv = findViewById(R.id.deadlinesTuesdayHeader); + tv.setText(tuesday); + tv = findViewById(R.id.deadlinesWednesdayHeader); + tv.setText(wednesday); + tv = findViewById(R.id.deadlinesThursdayHeader); + tv.setText(thursday); + tv = findViewById(R.id.deadlinesFridayHeader); + tv.setText(friday); + tv = findViewById(R.id.deadlinesSaturdayHeader); + tv.setText(saturday); + tv = findViewById(R.id.deadlinesSundayHeader); + tv.setText(sunday); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_deadlines); + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + DrawerLayout drawer = findViewById(R.id.drawer_layout); + ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( + this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); + drawer.addDrawerListener(toggle); + toggle.syncState(); + + NavigationView navigationView = findViewById(R.id.nav_view); + navigationView.setNavigationItemSelectedListener(this); + + setTitle(getString(R.string.deadlineHeader)); + + localDate = (LocalDate) getIntent().getSerializableExtra("date"); + + setHeaders(); + outputDeadlines(); + + Button nextWeekButton = findViewById(R.id.nextWeekButton); + nextWeekButton.setText(R.string.next_week); + nextWeekButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + localDate = localDate.plusDays(7); + setHeaders(); + outputDeadlines(); + } + }); + + Button button = findViewById(R.id.previousWeekButton); + button.setText(getResources().getString(R.string.previous_week)); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + localDate = localDate.minusDays(7); + setHeaders(); + outputDeadlines(); + } + }); + } + + @Override + public void onBackPressed() { + DrawerLayout drawer = findViewById(R.id.drawer_layout); + if (drawer.isDrawerOpen(GravityCompat.START)) { + drawer.closeDrawer(GravityCompat.START); + } else { + super.onBackPressed(); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.deadlines, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.action_settings) { + return true; + } + + return super.onOptionsItemSelected(item); + } + + @SuppressWarnings("StatementWithEmptyBody") + @Override + public boolean onNavigationItemSelected(@NotNull MenuItem item) { + // Handle navigation view item clicks here. + int id = item.getItemId(); + + if (id == R.id.nav_main) { + Intent intent = new Intent(this, MainActivity.class); + startActivity(intent); + } else if (id == R.id.nav_deadlines) { + Intent intent = new Intent(this, DeadlinesActivity.class); + intent.putExtra("date", new LocalDate()); + startActivityForResult(intent, 1); + } else if (id == R.id.nav_homework) { + Intent intent = new Intent(this, HomeworkActivity.class); + startActivityForResult(intent, 1); + } else if (id == R.id.nav_schedule) { + Intent intent = new Intent(this, ScheduleActivity.class); + intent.putExtra("date", new LocalDate()); + startActivityForResult(intent, 1); + + } /*else if (id == R.id.nav_studymaterials) { + Intent intent = new Intent(this, StudyMaterialsActivity.class); + startActivityForResult(intent, 1); + }*/ + + DrawerLayout drawer = findViewById(R.id.drawer_layout); + drawer.closeDrawer(GravityCompat.START); + return true; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + outputDeadlines(); + } +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/DisplayHomeworkActivity.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/DisplayHomeworkActivity.java new file mode 100644 index 0000000..d295fa3 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/DisplayHomeworkActivity.java @@ -0,0 +1,102 @@ +package ru.spbau.group202.notdeadbydeadline.ui; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.PopupMenu; +import android.support.v7.widget.Toolbar; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListView; + +import org.joda.time.LocalDate; + +import java.util.List; + +import ru.spbau.group202.notdeadbydeadline.controller.Controller; +import ru.spbau.group202.notdeadbydeadline.R; + + +public class DisplayHomeworkActivity extends AppCompatActivity { + + + private void outputHomeworksBySubject(String subject) { + List> formattedHomeworksDetails = + Controller.HomeworkController.getHomeworksBySubject(subject); + + ListView homeworksListView = findViewById(R.id.homeworksListView); + HomeworkListViewAdapter adapter1 = new HomeworkListViewAdapter(this, formattedHomeworksDetails); + homeworksListView.setAdapter(adapter1); + } + + private void processOnLongTapHomework() { + ListView homeworksListView = findViewById(R.id.homeworksListView); + homeworksListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + PopupMenu popup = new PopupMenu(DisplayHomeworkActivity.this, view); + popup.getMenuInflater() + .inflate(R.menu.listview_item_menu, popup.getMenu()); + //registering popup with OnMenuItemClickListener + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + if (item.getTitle().toString().equals(getResources() + .getString(R.string.lv_entry_edit))) { + List detailedEntryList = (List) parent.getItemAtPosition(position); + int id = Integer.parseInt(detailedEntryList.get(detailedEntryList.size() - 1)); + Intent intent = new Intent(DisplayHomeworkActivity.this, AddHomeworkActivity.class); + intent.putExtra("id", id); + startActivityForResult(intent, 1); + return true; + } else if (item.getTitle().toString().equals(getResources() + .getString(R.string.lv_entry_delete))) { + List detailedEntryList = (List) parent.getItemAtPosition(position); + Controller.HomeworkController.deleteHomeworkById(Integer.parseInt(detailedEntryList.get(detailedEntryList.size() - 1))); + recreate(); + return true; + } + + return false; + } + }); + + popup.show(); //showing popup menu + return true; + } + }); + + + } + + private void outputHomeworks() { + String subject = getIntent().getStringExtra("SUBJECT_NAME"); + setTitle(subject); + + outputHomeworksBySubject(subject); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + outputHomeworks(); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_display_homework); + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + String subject = getIntent().getStringExtra("SUBJECT_NAME"); + setTitle(subject); + + //outputHomeworksBySubject(subject); + outputHomeworks(); + processOnLongTapHomework(); + } + +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/HomeworkActivity.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/HomeworkActivity.java new file mode 100644 index 0000000..4a86cdd --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/HomeworkActivity.java @@ -0,0 +1,146 @@ +package ru.spbau.group202.notdeadbydeadline.ui; + +import android.content.Intent; +import android.os.Bundle; +import android.support.design.widget.FloatingActionButton; +import android.view.View; +import android.support.design.widget.NavigationView; +import android.support.v4.view.GravityCompat; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.app.ActionBarDrawerToggle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListView; + +import org.jetbrains.annotations.NotNull; +import org.joda.time.LocalDate; + +import java.util.List; + +import ru.spbau.group202.notdeadbydeadline.controller.Controller; +import ru.spbau.group202.notdeadbydeadline.R; + +public class HomeworkActivity extends AppCompatActivity + implements NavigationView.OnNavigationItemSelectedListener { + + private void displaySubjects() { + List subjects = Controller.getSubjectList(); + + final ListView lv = findViewById(R.id.subjectListView); + ArrayAdapter adapter = new ArrayAdapter<>(this, + R.layout.custom_textview_for_bigger_listview, subjects); + lv.setAdapter(adapter); + lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Intent intent = new Intent(getApplicationContext(), DisplayHomeworkActivity.class); + intent.putExtra("SUBJECT_NAME", (String) lv.getItemAtPosition(position)); + startActivity(intent); + } + }); + } + + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + displaySubjects(); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_homework); + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + FloatingActionButton fab = findViewById(R.id.fab); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(getApplicationContext(), AddHomeworkActivity.class); + startActivityForResult(intent, 1); + } + }); + + DrawerLayout drawer = findViewById(R.id.drawer_layout); + ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( + this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); + drawer.addDrawerListener(toggle); + toggle.syncState(); + + NavigationView navigationView = findViewById(R.id.nav_view); + navigationView.setNavigationItemSelectedListener(this); + + setTitle("Homeworks"); + + displaySubjects(); + } + + @Override + public void onBackPressed() { + DrawerLayout drawer = findViewById(R.id.drawer_layout); + if (drawer.isDrawerOpen(GravityCompat.START)) { + drawer.closeDrawer(GravityCompat.START); + } else { + super.onBackPressed(); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.homework, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.action_settings) { + return true; + } + + return super.onOptionsItemSelected(item); + } + + @SuppressWarnings("StatementWithEmptyBody") + @Override + public boolean onNavigationItemSelected(@NotNull MenuItem item) { + // Handle navigation view item clicks here. + int id = item.getItemId(); + + + if (id == R.id.nav_main) { + Intent intent = new Intent(this, MainActivity.class); + startActivity(intent); + } else if (id == R.id.nav_deadlines) { + Intent intent = new Intent(this, DeadlinesActivity.class); + intent.putExtra("date", new LocalDate()); + startActivityForResult(intent, 1); + } else if (id == R.id.nav_homework) { + Intent intent = new Intent(this, HomeworkActivity.class); + startActivityForResult(intent, 1); + } else if (id == R.id.nav_schedule) { + Intent intent = new Intent(this, ScheduleActivity.class); + intent.putExtra("date", new LocalDate()); + startActivityForResult(intent, 1); + + }/* else if (id == R.id.nav_studymaterials) { + Intent intent = new Intent(this, StudyMaterialsActivity.class); + startActivityForResult(intent, 1); + }*/ + + DrawerLayout drawer = findViewById(R.id.drawer_layout); + drawer.closeDrawer(GravityCompat.START); + return true; + } +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/HomeworkListViewAdapter.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/HomeworkListViewAdapter.java new file mode 100644 index 0000000..4ae9714 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/HomeworkListViewAdapter.java @@ -0,0 +1,89 @@ +package ru.spbau.group202.notdeadbydeadline.ui; + +import android.content.Context; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.style.StyleSpan; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; + +import ru.spbau.group202.notdeadbydeadline.R; + +import static android.graphics.Typeface.BOLD; + +public class HomeworkListViewAdapter extends BaseAdapter { + private LayoutInflater lInflater; + private List> detailedEntries; + + HomeworkListViewAdapter(Context context, + List> detailedEntries) { + this.detailedEntries = detailedEntries; + lInflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + } + + @Override + public int getCount() { + return detailedEntries.size(); + } + + @Override + public Object getItem(int position) { + return detailedEntries.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + @SuppressWarnings("unchecked") + public View getView(int position, View convertView, ViewGroup parent) { + + View view = convertView; + if (view == null) { + view = lInflater.inflate(R.layout.custom_homework_listview_item, parent, false); + } + + ArrayList detailedEntry = (ArrayList) getItem(position); + + String deadlinesField = "\nDeadline: "; + String descriptionFiled = "\nDescription: "; + String submitField = "\nSubmit: "; + String expectedScoreField = "\nExpected Score: "; + + SpannableStringBuilder stringBuilder = new SpannableStringBuilder(descriptionFiled); + stringBuilder.setSpan(new StyleSpan(BOLD), + 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + stringBuilder.append(detailedEntry.get(0)); + stringBuilder.append(deadlinesField); + stringBuilder.setSpan(new StyleSpan(BOLD), + stringBuilder.length() - deadlinesField.length(), + stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + stringBuilder.append(detailedEntry.get(1)); + stringBuilder.append(submitField); + stringBuilder.setSpan(new StyleSpan(BOLD), + stringBuilder.length() - submitField.length(), + stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + stringBuilder.append(detailedEntry.get(2)); + stringBuilder.append(expectedScoreField); + stringBuilder.setSpan(new StyleSpan(BOLD), + stringBuilder.length() - expectedScoreField.length(), + stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + stringBuilder.append(detailedEntry.get(3)); + + + ((TextView) view.findViewById(R.id.list_item_hw)).setText(stringBuilder); + + return view; + } + + +} \ No newline at end of file diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/MainActivity.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/MainActivity.java new file mode 100644 index 0000000..eddb432 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/MainActivity.java @@ -0,0 +1,221 @@ +package ru.spbau.group202.notdeadbydeadline.ui; + +import android.content.Intent; +import android.graphics.Typeface; +import android.os.Bundle; +import android.text.SpannableString; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.style.RelativeSizeSpan; +import android.text.style.StyleSpan; +import android.support.design.widget.NavigationView; +import android.support.v4.view.GravityCompat; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.app.ActionBarDrawerToggle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.TextView; + +import net.danlew.android.joda.JodaTimeAndroid; + +import org.jetbrains.annotations.NotNull; +import org.joda.time.LocalDate; +import org.joda.time.LocalDateTime; + +import java.util.ArrayList; +import java.util.List; + +import ru.spbau.group202.notdeadbydeadline.controller.Controller; +import ru.spbau.group202.notdeadbydeadline.R; +import ru.spbau.group202.notdeadbydeadline.model.WeekParityEnum; + +public class MainActivity extends AppCompatActivity + implements NavigationView.OnNavigationItemSelectedListener { + + private void outputCurrentDate() { + LocalDateTime currentDate = LocalDateTime.now(); + + StringBuilder dateStringBuilder = + new StringBuilder(Integer.toString(currentDate.getDayOfMonth())); + dateStringBuilder.append("\n"); + dateStringBuilder.append(currentDate.monthOfYear().getAsText()); + dateStringBuilder.append("\n"); + int pos = dateStringBuilder.length(); + dateStringBuilder.append(currentDate.dayOfWeek().getAsText()); + String dateString = dateStringBuilder.toString(); + + SpannableString date = new SpannableString(dateString); + date.setSpan(new RelativeSizeSpan(3f), 0, 2, 0); + date.setSpan(new StyleSpan(Typeface.ITALIC), pos, dateString.length(), 0); + + TextView tv = findViewById(R.id.currentDate); + tv.setText(date); + tv.setFocusable(false); + } + + private void outputDeadlines() { + List> deadlinesDetails = Controller.HomeworkController + .getDeadlinesByDay(LocalDate.now()); + + + LocalDateTime ldt = LocalDateTime.now().plusDays(1); + deadlinesDetails.addAll(Controller.HomeworkController + .getDeadlinesByDay(ldt.toLocalDate())); + + + ArrayList formattedDeadlines = new ArrayList<>(); + for (List deadlineDetails : deadlinesDetails) { + SpannableStringBuilder stringBuilder = new SpannableStringBuilder( + deadlineDetails.get(2)); + + int position = stringBuilder.length(); + stringBuilder.append(" "); + stringBuilder.append(deadlineDetails.get(0)); + stringBuilder.setSpan(new StyleSpan(Typeface.BOLD), + position, stringBuilder.length(), + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + if (!deadlineDetails.get(1).isEmpty()) { + stringBuilder.append("\n"); + stringBuilder.append(deadlineDetails.get(1)); + } + + formattedDeadlines.add(stringBuilder); + } + + ListView lv = findViewById(R.id.deadlinesList2); + ArrayAdapter adapter = new ArrayAdapter<>(this, + R.layout.custom_mainscreen_listview_entry, + formattedDeadlines); + lv.setAdapter(adapter); + } + + private void outputTodaySchedule() { + LocalDate localDate = LocalDate.now(); + List> scheduleDetails = Controller.ScheduleController.getScheduleByDay(localDate); + /*List> scheduleDetails = Controller.ScheduleController.getScheduleByDayOfWeek(localDate.getDayOfWeek() - 1, + WeekParityEnum.values()[localDate.getWeekOfWeekyear() % 2]);*/ + + ArrayList formattedSchedule = new ArrayList<>(); + for (int i = 0; i < scheduleDetails.size(); i++) { + List schDetails = scheduleDetails.get(i); + SpannableStringBuilder stringBuilder = + new SpannableStringBuilder(schDetails.get(1)); + + stringBuilder.append(" "); + int position = stringBuilder.length(); + stringBuilder.append(schDetails.get(0)); + stringBuilder.setSpan(new StyleSpan(Typeface.BOLD), + position, stringBuilder.length(), + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + stringBuilder.append(", \n"); + stringBuilder.append(schDetails.get(2)); + stringBuilder.append(", "); + stringBuilder.append(schDetails.get(3)); + + formattedSchedule.add(stringBuilder); + } + + ListView lv = findViewById(R.id.scheduleListViewMainScreen); + ArrayAdapter adapter = new ArrayAdapter<>(this, + R.layout.custom_mainscreen_listview_entry, + formattedSchedule); + lv.setAdapter(adapter); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + JodaTimeAndroid.init(this); + + DrawerLayout drawer = findViewById(R.id.drawer_layout); + ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( + this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); + drawer.addDrawerListener(toggle); + toggle.syncState(); + + NavigationView navigationView = findViewById(R.id.nav_view); + navigationView.setNavigationItemSelectedListener(this); + + Controller.createDatabases(this); + + outputCurrentDate(); + outputDeadlines(); + outputTodaySchedule(); + } + + @Override + public void onBackPressed() { + DrawerLayout drawer = findViewById(R.id.drawer_layout); + if (drawer.isDrawerOpen(GravityCompat.START)) { + drawer.closeDrawer(GravityCompat.START); + } else { + super.onBackPressed(); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.action_settings) { + return true; + } + + return super.onOptionsItemSelected(item); + } + + @SuppressWarnings("StatementWithEmptyBody") + @Override + public boolean onNavigationItemSelected(@NotNull MenuItem item) { + // Handle navigation view item clicks here. + int id = item.getItemId(); + + if (id == R.id.nav_main) { + Intent intent = new Intent(this, MainActivity.class); + startActivity(intent); + } else if (id == R.id.nav_deadlines) { + Intent intent = new Intent(this, DeadlinesActivity.class); + intent.putExtra("date", new LocalDate()); + startActivityForResult(intent, 1); + } else if (id == R.id.nav_homework) { + Intent intent = new Intent(this, HomeworkActivity.class); + startActivityForResult(intent, 1); + } else if (id == R.id.nav_schedule) { + Intent intent = new Intent(this, ScheduleActivity.class); + intent.putExtra("date", new LocalDate()); + startActivityForResult(intent, 1); + } /*else if (id == R.id.nav_studymaterials) { + Intent intent = new Intent(this, StudyMaterialsActivity.class); + startActivityForResult(intent, 1); + }*/ + + DrawerLayout drawer = findViewById(R.id.drawer_layout); + drawer.closeDrawer(GravityCompat.START); + return true; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + outputDeadlines(); + outputTodaySchedule(); + } +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/ScheduleActivity.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/ScheduleActivity.java new file mode 100644 index 0000000..77f98e7 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/ScheduleActivity.java @@ -0,0 +1,319 @@ +package ru.spbau.group202.notdeadbydeadline.ui; + +import android.content.Intent; +import android.graphics.Typeface; +import android.os.Bundle; +import android.support.design.widget.FloatingActionButton; +import android.support.v7.widget.PopupMenu; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.style.StyleSpan; +import android.util.Log; +import android.view.View; +import android.support.design.widget.NavigationView; +import android.support.v4.view.GravityCompat; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.app.ActionBarDrawerToggle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.ListView; +import android.widget.TableLayout; +import android.widget.TextView; + +import org.jetbrains.annotations.NotNull; +import org.joda.time.DateTimeConstants; +import org.joda.time.LocalDate; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import ru.spbau.group202.notdeadbydeadline.controller.Controller; +import ru.spbau.group202.notdeadbydeadline.R; +import ru.spbau.group202.notdeadbydeadline.model.WeekParityEnum; +import ru.spbau.group202.notdeadbydeadline.ui.utilities.ListViewUtility; + +public class ScheduleActivity extends AppCompatActivity + implements NavigationView.OnNavigationItemSelectedListener { + + private static final String TAG = "ScheduleActivity"; + + private LocalDate localDate; + + private void outputScheduleByDay(int dayNumber) { + List> scheduleDetails = Controller.ScheduleController.getScheduleByDay(localDate.plusDays(dayNumber)); + //List> scheduleDetails = Controller.ScheduleController.getScheduleByDayOfWeek(dayNumber, + //WeekParityEnum.values()[localDate.getWeekOfWeekyear() % 2]); + + /*ArrayList formattedSchedule = new ArrayList<>(); + for (int i = 0; i < scheduleDetails.size(); i++) { + List schDetails = scheduleDetails.get(i); + SpannableStringBuilder stringBuilder = + new SpannableStringBuilder(schDetails.get(1)); + + stringBuilder.append(" "); + int position = stringBuilder.length(); + stringBuilder.append(schDetails.get(0)); + stringBuilder.setSpan(new StyleSpan(Typeface.BOLD), + position, stringBuilder.length(), + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + stringBuilder.append(", \n"); + stringBuilder.append(schDetails.get(2)); + stringBuilder.append(", "); + stringBuilder.append(schDetails.get(3)); + + formattedSchedule.add(stringBuilder); + }*/ + + ListView lv; + switch (dayNumber + 1) { + case DateTimeConstants.MONDAY: + lv = findViewById(R.id.scheduleMondayList); + break; + case DateTimeConstants.TUESDAY: + lv = findViewById(R.id.scheduleTuesdayList); + break; + case DateTimeConstants.WEDNESDAY: + lv = findViewById(R.id.scheduleWednesdayList); + break; + case DateTimeConstants.THURSDAY: + lv = findViewById(R.id.scheduleThursdayList); + break; + case DateTimeConstants.FRIDAY: + lv = findViewById(R.id.scheduleFridayList); + break; + case DateTimeConstants.SATURDAY: + lv = findViewById(R.id.scheduleSaturdayList); + break; + default: + Log.e(TAG, "Wrong dayNumber parameter in OutputScheduleByDay"); + return; + } + + ScheduleListViewAdapter adapter = new ScheduleListViewAdapter(this, scheduleDetails); + lv.setAdapter(adapter); + } + + private void setHeaders() { + + String monday = getResources().getString(R.string.monday); + String tuesday = getResources().getString(R.string.tuesday); + String wednesday = getResources().getString(R.string.wednesday); + String thursday = getResources().getString(R.string.thursday); + String friday = getResources().getString(R.string.friday); + String saturday = getResources().getString(R.string.saturday); + + TextView tv = findViewById(R.id.scheduleMondayHeader); + tv.setText(monday); + tv = findViewById(R.id.scheduleTuesdayHeader); + tv.setText(tuesday); + tv = findViewById(R.id.scheduleWednesdayHeader); + tv.setText(wednesday); + tv = findViewById(R.id.scheduleThursdayHeader); + tv.setText(thursday); + tv = findViewById(R.id.scheduleFridayHeader); + tv.setText(friday); + tv = findViewById(R.id.scheduleSaturdayHeader); + tv.setText(saturday); + } + + private void setListViewsHeightAllDays() { + ListView monday = findViewById(R.id.scheduleMondayList); + ListView tuesday = findViewById(R.id.scheduleTuesdayList); + ListView wednesday = findViewById(R.id.scheduleWednesdayList); + ListView thursday = findViewById(R.id.scheduleThursdayList); + ListView friday = findViewById(R.id.scheduleFridayList); + ListView saturday = findViewById(R.id.scheduleSaturdayList); + + ListViewUtility.setTwoListViewsHeight(monday, thursday); + ListViewUtility.setTwoListViewsHeight(tuesday, friday); + ListViewUtility.setTwoListViewsHeight(wednesday, saturday); + } + + private void outputSchedule() { + final TableLayout table = findViewById(R.id.scheduleTableLayout); + table.setColumnShrinkable(0, true); + table.setColumnShrinkable(1, true); + + for (int i = 0; i <= 5; ++i) + outputScheduleByDay(i); + + setListViewsHeightAllDays(); + } + + private void processOnLongTapScheduleEntry(int listViewId) { + ListView scheduleListView = findViewById(listViewId); + scheduleListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + PopupMenu popup = new PopupMenu(ScheduleActivity.this, view); + popup.getMenuInflater() + .inflate(R.menu.listview_item_menu, popup.getMenu()); + //registering popup with OnMenuItemClickListener + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + if (item.getTitle().toString().equals(getResources() + .getString(R.string.lv_entry_edit))) { + // TODO call edit (which is yet nonexistent) + return true; + } else if (item.getTitle().toString().equals(getResources() + .getString(R.string.lv_entry_delete))) { + List detailedEntryList = (List) parent.getItemAtPosition(position); + Controller.ScheduleController.deleteScheduleEntryById( + Integer.parseInt(detailedEntryList.get(detailedEntryList.size() - 1))); + recreate(); + return true; + } + + return false; + } + }); + + popup.show(); //showing popup menu + return true; + } + }); + + } + + private void processListviewLongTapForAllWeekdays() { + processOnLongTapScheduleEntry(R.id.scheduleMondayList); + processOnLongTapScheduleEntry(R.id.scheduleTuesdayList); + processOnLongTapScheduleEntry(R.id.scheduleWednesdayList); + processOnLongTapScheduleEntry(R.id.scheduleThursdayList); + processOnLongTapScheduleEntry(R.id.scheduleFridayList); + processOnLongTapScheduleEntry(R.id.scheduleSaturdayList); + } + + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_schedule); + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + FloatingActionButton fab = findViewById(R.id.addScheduleEntryButton); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(getApplicationContext(), AddScheduleEntryActivity.class); + startActivityForResult(intent, 1); + } + }); + + DrawerLayout drawer = findViewById(R.id.drawer_layout); + ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( + this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); + drawer.addDrawerListener(toggle); + toggle.syncState(); + + NavigationView navigationView = findViewById(R.id.nav_view); + navigationView.setNavigationItemSelectedListener(this); + + localDate = (LocalDate) getIntent().getSerializableExtra("date"); + + setTitle("Schedule"); + setHeaders(); + outputSchedule(); + + Button nextWeekButton = findViewById(R.id.scheduleNextWeekButton); + nextWeekButton.setText(R.string.next_week); + nextWeekButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + localDate = localDate.plusDays(7); + setHeaders(); + outputSchedule(); + } + }); + + Button button = findViewById(R.id.schedulePreviousWeekButton); + button.setText(getResources().getString(R.string.previous_week)); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + localDate = localDate.minusDays(7); + setHeaders(); + outputSchedule(); + } + }); + + processListviewLongTapForAllWeekdays(); + } + + @Override + public void onBackPressed() { + DrawerLayout drawer = findViewById(R.id.drawer_layout); + if (drawer.isDrawerOpen(GravityCompat.START)) { + drawer.closeDrawer(GravityCompat.START); + } else { + super.onBackPressed(); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.schedule, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.action_settings) { + return true; + } + + return super.onOptionsItemSelected(item); + } + + @SuppressWarnings("StatementWithEmptyBody") + @Override + public boolean onNavigationItemSelected(@NotNull MenuItem item) { + // Handle navigation view item clicks here. + int id = item.getItemId(); + + if (id == R.id.nav_main) { + Intent intent = new Intent(this, MainActivity.class); + startActivity(intent); + } else if (id == R.id.nav_deadlines) { + Intent intent = new Intent(this, DeadlinesActivity.class); + intent.putExtra("date", new LocalDate()); + startActivityForResult(intent, 1); + } else if (id == R.id.nav_homework) { + Intent intent = new Intent(this, HomeworkActivity.class); + startActivityForResult(intent, 1); + } else if (id == R.id.nav_schedule) { + Intent intent = new Intent(this, ScheduleActivity.class); + intent.putExtra("date", new LocalDate()); + startActivityForResult(intent, 1); + } /*else if (id == R.id.nav_studymaterials) { + Intent intent = new Intent(this, StudyMaterialsActivity.class); + startActivityForResult(intent, 1); + }*/ + + DrawerLayout drawer = findViewById(R.id.drawer_layout); + drawer.closeDrawer(GravityCompat.START); + return true; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + outputSchedule(); + } +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/ScheduleListViewAdapter.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/ScheduleListViewAdapter.java new file mode 100644 index 0000000..1a38966 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/ScheduleListViewAdapter.java @@ -0,0 +1,77 @@ +package ru.spbau.group202.notdeadbydeadline.ui; + +import android.content.Context; +import android.graphics.Typeface; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.style.StyleSpan; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; + +import ru.spbau.group202.notdeadbydeadline.R; + +public class ScheduleListViewAdapter extends BaseAdapter { + + private LayoutInflater lInflater; + private List> detailedEntries; + + ScheduleListViewAdapter(Context context, + List> detailedEntries) { + this.detailedEntries = detailedEntries; + lInflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + } + + @Override + public int getCount() { + return detailedEntries.size(); + } + + @Override + public Object getItem(int position) { + return detailedEntries.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + @SuppressWarnings("unchecked") + public View getView(int position, View convertView, ViewGroup parent) { + + View view = convertView; + if (view == null) { + view = lInflater.inflate(R.layout.custom_schedule_listview_item, parent, false); + } + + ArrayList detailedEntry = (ArrayList) getItem(position); + + SpannableStringBuilder stringBuilder = new SpannableStringBuilder(detailedEntry.get(1)); + stringBuilder.append(" "); + int pos = stringBuilder.length(); + stringBuilder.append(detailedEntry.get(0)); + stringBuilder.setSpan(new StyleSpan(Typeface.BOLD), + pos, stringBuilder.length(), + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + if (!detailedEntry.get(2).isEmpty() && !detailedEntry.get(3).isEmpty()) { + stringBuilder.append(", \n"); + if (!detailedEntry.get(2).isEmpty()) { + stringBuilder.append(detailedEntry.get(2)); + stringBuilder.append(", "); + } + stringBuilder.append(detailedEntry.get(3)); + } + + ((TextView) view.findViewById(R.id.list_item_sch)).setText(stringBuilder); + + return view; + } +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/AbstractDatePicker.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/AbstractDatePicker.java new file mode 100644 index 0000000..b51bbbc --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/AbstractDatePicker.java @@ -0,0 +1,39 @@ +package ru.spbau.group202.notdeadbydeadline.ui.utilities; + +import android.app.DatePickerDialog; +import android.app.Dialog; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; + +import org.jetbrains.annotations.NotNull; +import org.joda.time.LocalDate; + +public abstract class AbstractDatePicker extends DialogFragment + implements DatePickerDialog.OnDateSetListener { + private int year; + private int month; + private int day; + + public AbstractDatePicker() { + + // Use the current date as the default date in the picker + LocalDate localDate = new LocalDate(); + year = localDate.getYear(); + month = localDate.getMonthOfYear() - 1; + day = localDate.getDayOfMonth(); + } + + public void setValues(int year, int month, int day) { + this.year = year; + this.month = month; + this.day = day; + } + + @NotNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + + // Create a new instance of DatePickerDialog and return it + return new DatePickerDialog(getActivity(), this, year, month, day); + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/AbstractTimePicker.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/AbstractTimePicker.java new file mode 100644 index 0000000..f9c9584 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/AbstractTimePicker.java @@ -0,0 +1,39 @@ +package ru.spbau.group202.notdeadbydeadline.ui.utilities; + +import android.app.Dialog; +import android.app.TimePickerDialog; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.text.format.DateFormat; + +import org.jetbrains.annotations.NotNull; +import org.joda.time.LocalTime; + +public abstract class AbstractTimePicker extends DialogFragment + implements TimePickerDialog.OnTimeSetListener { + + private int hour; + private int minute; + + public AbstractTimePicker() { + // Use the current time as the default values for the picker + LocalTime localTime = new LocalTime(); + hour = localTime.getHourOfDay(); + minute = localTime.getMinuteOfHour(); + } + + public void setValues(int hour, int minute) { + this.hour = hour; + this.minute = minute; + } + + @NotNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + + + // Create a new instance of TimePickerDialog and return it + return new TimePickerDialog(getActivity(), this, hour, minute, + DateFormat.is24HourFormat(getActivity())); + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/ListViewUtility.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/ListViewUtility.java new file mode 100644 index 0000000..a4398a2 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/ListViewUtility.java @@ -0,0 +1,39 @@ +package ru.spbau.group202.notdeadbydeadline.ui.utilities; + +import android.view.View; +import android.view.ViewGroup; +import android.widget.ListAdapter; +import android.widget.ListView; + +public class ListViewUtility { + + // set listView2 height based on listView1 height + private static void setListViewHeightBasedOnChildren(ListView listView1, + ListView listView2) { + ListAdapter listAdapter = listView1.getAdapter(); + if (listAdapter == null) { + // pre-condition + return; + } + int totalHeight = 0; + for (int i = 0; i < listAdapter.getCount(); i++) { + View listItem = listAdapter.getView(i, null, listView1); + listItem.measure(0, 0); + totalHeight += listItem.getMeasuredHeight(); + } + + ViewGroup.LayoutParams params = listView2.getLayoutParams(); + params.height = totalHeight + (listView2.getDividerHeight() * (listAdapter.getCount() - 1)); + listView2.setLayoutParams(params); + } + + public static void setTwoListViewsHeight(ListView listView1, ListView listView2) { + if (listView1.getAdapter().getCount() > listView2.getAdapter().getCount()) { + setListViewHeightBasedOnChildren(listView1, listView2); + setListViewHeightBasedOnChildren(listView1, listView1); + } else { + setListViewHeightBasedOnChildren(listView2, listView2); + setListViewHeightBasedOnChildren(listView2, listView1); + } + } +} diff --git a/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/WeekDayEnum.java b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/WeekDayEnum.java new file mode 100644 index 0000000..aeec4b7 --- /dev/null +++ b/app/src/main/java/ru/spbau/group202/notdeadbydeadline/ui/utilities/WeekDayEnum.java @@ -0,0 +1,5 @@ +package ru.spbau.group202.notdeadbydeadline.ui.utilities; + +public enum WeekDayEnum { + Monday, Tuesday, Wednesday, Thursday, Friday, Saturday; +} diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..c7bd21d --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..d5fccc5 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_note_add_white_24dp.xml b/app/src/main/res/drawable/ic_note_add_white_24dp.xml new file mode 100644 index 0000000..750127b --- /dev/null +++ b/app/src/main/res/drawable/ic_note_add_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/side_nav_bar.xml b/app/src/main/res/drawable/side_nav_bar.xml new file mode 100644 index 0000000..6d81870 --- /dev/null +++ b/app/src/main/res/drawable/side_nav_bar.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_add_homework.xml b/app/src/main/res/layout/activity_add_homework.xml new file mode 100644 index 0000000..4e01f11 --- /dev/null +++ b/app/src/main/res/layout/activity_add_homework.xml @@ -0,0 +1,112 @@ + + + + + + + +