├── settings.gradle
├── metadata
└── en-US
│ ├── title.txt
│ ├── images
│ ├── icon.png
│ ├── icon-raw.png
│ └── phoneScreenshots
│ │ ├── 1.png
│ │ ├── 2.png
│ │ ├── 3.png
│ │ ├── 4.png
│ │ ├── 5.png
│ │ ├── 6.png
│ │ ├── 7.png
│ │ ├── 8.png
│ │ └── 9.png
│ └── short_description.txt
├── .gitignore
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── app
├── src
│ ├── main
│ │ ├── ic_launcher-playstore.png
│ │ ├── res
│ │ │ ├── drawable
│ │ │ │ ├── backup_ok.png
│ │ │ │ ├── backup_not_ok.png
│ │ │ │ ├── widget_preview.png
│ │ │ │ ├── side_nav_bar.xml
│ │ │ │ ├── ic_navigate_arrow_left.xml
│ │ │ │ ├── item_drawable.xml
│ │ │ │ ├── widget_background.xml
│ │ │ │ ├── ic_calendar_recenter_left.xml
│ │ │ │ ├── ic_calendar_recenter_right.xml
│ │ │ │ ├── ic_navigate_arrow_right.xml
│ │ │ │ ├── ic_download.xml
│ │ │ │ ├── ic_menu_box_closed.xml
│ │ │ │ └── ic_menu_box_open.xml
│ │ │ ├── drawable-hdpi
│ │ │ │ ├── ic_play.png
│ │ │ │ ├── ic_stop.png
│ │ │ │ ├── ic_menu_add.png
│ │ │ │ ├── ic_menu_edit.png
│ │ │ │ ├── ic_menu_mark.png
│ │ │ │ ├── ic_menu_star.png
│ │ │ │ ├── ic_menu_agenda.png
│ │ │ │ ├── ic_menu_compass.png
│ │ │ │ ├── ic_menu_delete.png
│ │ │ │ ├── ic_menu_forward.png
│ │ │ │ ├── ic_menu_revert.png
│ │ │ │ ├── ic_notification.png
│ │ │ │ ├── ic_menu_info_details.png
│ │ │ │ ├── ic_menu_mylocation.png
│ │ │ │ ├── ic_menu_preferences.png
│ │ │ │ ├── ic_menu_sort_by_size.png
│ │ │ │ └── ic_menu_close_clear_cancel.png
│ │ │ ├── drawable-ldpi
│ │ │ │ ├── ic_play.png
│ │ │ │ ├── ic_stop.png
│ │ │ │ ├── ic_menu_add.png
│ │ │ │ ├── ic_menu_edit.png
│ │ │ │ ├── ic_menu_mark.png
│ │ │ │ ├── ic_menu_star.png
│ │ │ │ ├── ic_menu_agenda.png
│ │ │ │ ├── ic_menu_compass.png
│ │ │ │ ├── ic_menu_delete.png
│ │ │ │ ├── ic_menu_forward.png
│ │ │ │ ├── ic_menu_revert.png
│ │ │ │ ├── ic_notification.png
│ │ │ │ ├── ic_menu_info_details.png
│ │ │ │ ├── ic_menu_mylocation.png
│ │ │ │ ├── ic_menu_preferences.png
│ │ │ │ ├── ic_menu_sort_by_size.png
│ │ │ │ └── ic_menu_close_clear_cancel.png
│ │ │ ├── drawable-mdpi
│ │ │ │ ├── ic_play.png
│ │ │ │ ├── ic_stop.png
│ │ │ │ ├── ic_menu_add.png
│ │ │ │ ├── ic_menu_edit.png
│ │ │ │ ├── ic_menu_mark.png
│ │ │ │ ├── ic_menu_star.png
│ │ │ │ ├── ic_menu_agenda.png
│ │ │ │ ├── ic_menu_compass.png
│ │ │ │ ├── ic_menu_delete.png
│ │ │ │ ├── ic_menu_forward.png
│ │ │ │ ├── ic_menu_revert.png
│ │ │ │ ├── ic_notification.png
│ │ │ │ ├── ic_menu_info_details.png
│ │ │ │ ├── ic_menu_mylocation.png
│ │ │ │ ├── ic_menu_preferences.png
│ │ │ │ ├── ic_menu_sort_by_size.png
│ │ │ │ └── ic_menu_close_clear_cancel.png
│ │ │ ├── xml
│ │ │ │ ├── shortcuts.xml
│ │ │ │ ├── provider_paths.xml
│ │ │ │ └── widget_info.xml
│ │ │ ├── drawable-xhdpi
│ │ │ │ ├── ic_play.png
│ │ │ │ ├── ic_stop.png
│ │ │ │ ├── ic_menu_add.png
│ │ │ │ ├── ic_menu_agenda.png
│ │ │ │ ├── ic_menu_delete.png
│ │ │ │ ├── ic_menu_edit.png
│ │ │ │ ├── ic_menu_mark.png
│ │ │ │ ├── ic_menu_revert.png
│ │ │ │ ├── ic_menu_star.png
│ │ │ │ ├── ic_menu_compass.png
│ │ │ │ ├── ic_menu_forward.png
│ │ │ │ ├── ic_notification.png
│ │ │ │ ├── ic_menu_mylocation.png
│ │ │ │ ├── ic_menu_preferences.png
│ │ │ │ ├── ic_menu_info_details.png
│ │ │ │ ├── ic_menu_sort_by_size.png
│ │ │ │ └── ic_menu_close_clear_cancel.png
│ │ │ ├── drawable-xxhdpi
│ │ │ │ ├── ic_play.png
│ │ │ │ ├── ic_stop.png
│ │ │ │ ├── ic_menu_add.png
│ │ │ │ ├── ic_menu_edit.png
│ │ │ │ ├── ic_menu_mark.png
│ │ │ │ ├── ic_menu_star.png
│ │ │ │ ├── ic_menu_agenda.png
│ │ │ │ ├── ic_menu_compass.png
│ │ │ │ ├── ic_menu_delete.png
│ │ │ │ ├── ic_menu_forward.png
│ │ │ │ ├── ic_menu_revert.png
│ │ │ │ ├── ic_notification.png
│ │ │ │ ├── ic_menu_mylocation.png
│ │ │ │ ├── ic_menu_info_details.png
│ │ │ │ ├── ic_menu_preferences.png
│ │ │ │ ├── ic_menu_sort_by_size.png
│ │ │ │ └── ic_menu_close_clear_cancel.png
│ │ │ ├── drawable-xxxhdpi
│ │ │ │ ├── ic_play.png
│ │ │ │ ├── ic_stop.png
│ │ │ │ ├── ic_menu_add.png
│ │ │ │ ├── ic_menu_edit.png
│ │ │ │ ├── ic_menu_mark.png
│ │ │ │ ├── ic_menu_star.png
│ │ │ │ ├── ic_menu_agenda.png
│ │ │ │ ├── ic_menu_delete.png
│ │ │ │ ├── ic_menu_revert.png
│ │ │ │ ├── ic_menu_compass.png
│ │ │ │ ├── ic_menu_forward.png
│ │ │ │ ├── ic_notification.png
│ │ │ │ ├── ic_menu_mylocation.png
│ │ │ │ ├── ic_menu_preferences.png
│ │ │ │ ├── ic_menu_info_details.png
│ │ │ │ ├── ic_menu_sort_by_size.png
│ │ │ │ └── ic_menu_close_clear_cancel.png
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── raw
│ │ │ │ └── about.txt
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── values
│ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── colors.xml
│ │ │ │ ├── styles.xml
│ │ │ │ └── themes.xml
│ │ │ ├── menu
│ │ │ │ ├── list_context_menu.xml
│ │ │ │ └── activity_main_drawer.xml
│ │ │ ├── layout
│ │ │ │ ├── tasks_activity.xml
│ │ │ │ ├── list_item_spinner.xml
│ │ │ │ ├── options_activity.xml
│ │ │ │ ├── list_activity.xml
│ │ │ │ ├── message.xml
│ │ │ │ ├── list_item_separator.xml
│ │ │ │ ├── list_item_inactive.xml
│ │ │ │ ├── view_timezone_select.xml
│ │ │ │ ├── report_preview.xml
│ │ │ │ ├── activity_debug.xml
│ │ │ │ ├── activity_upgrade.xml
│ │ │ │ ├── about.xml
│ │ │ │ ├── nav_header_main.xml
│ │ │ │ ├── activity_main.xml
│ │ │ │ ├── list_item.xml
│ │ │ │ ├── widget.xml
│ │ │ │ ├── widget_day.xml
│ │ │ │ └── widget_night.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── values-sw360dp
│ │ │ │ └── preference.xml
│ │ │ ├── drawable-sizes.txt
│ │ │ ├── xml-v31
│ │ │ │ └── widget_info.xml
│ │ │ ├── xml-v25
│ │ │ │ └── shortcuts.xml
│ │ │ └── values-night
│ │ │ │ └── themes.xml
│ │ └── java
│ │ │ └── org
│ │ │ └── zephyrsoft
│ │ │ └── trackworktime
│ │ │ ├── eventlist
│ │ │ ├── BaseEventItem.java
│ │ │ ├── EventSeparatorViewHolder.java
│ │ │ ├── EventSeparatorItem.java
│ │ │ ├── EventViewHolder.java
│ │ │ ├── EventItemMapper.java
│ │ │ └── EventItem.java
│ │ │ ├── util
│ │ │ ├── Updatable.java
│ │ │ ├── StringExtractionMethod.java
│ │ │ ├── FileUtil.java
│ │ │ ├── GenericFileProvider.java
│ │ │ ├── ForeignCall.java
│ │ │ ├── SeparatorIdentificationMethod.java
│ │ │ ├── ThemeUtil.java
│ │ │ ├── PermissionCollector.java
│ │ │ ├── ExternalNotificationManager.java
│ │ │ └── TinylogAndLogcatLogger.java
│ │ │ ├── database
│ │ │ └── MigrationCallback.java
│ │ │ ├── model
│ │ │ ├── PeriodEnum.java
│ │ │ ├── NightMode.java
│ │ │ ├── Report.java
│ │ │ ├── TimeInfo.java
│ │ │ ├── Unit.java
│ │ │ ├── Range.java
│ │ │ ├── Base.java
│ │ │ ├── Week.java
│ │ │ ├── CalcCacheEntry.java
│ │ │ ├── TargetWrapper.java
│ │ │ ├── WeekState.java
│ │ │ └── Target.java
│ │ │ ├── location
│ │ │ ├── LocationCallback.java
│ │ │ ├── Result.java
│ │ │ ├── CoordinateUtil.java
│ │ │ └── TrackingMethod.java
│ │ │ ├── Watchdog.java
│ │ │ ├── BootCompletedReceiver.java
│ │ │ ├── weektimes
│ │ │ ├── WeekStateLoaderFactory.java
│ │ │ ├── WeekStateLoader.java
│ │ │ ├── WeekStateCalculatorFactory.java
│ │ │ ├── WeekIndexConverter.java
│ │ │ └── WeekTimesViewHolder.java
│ │ │ ├── options
│ │ │ ├── Check.java
│ │ │ ├── TimePreferenceDialogFragment.java
│ │ │ ├── TimeZonePreference.java
│ │ │ ├── DurationPreference.java
│ │ │ ├── FlexiIntervalPreference.java
│ │ │ ├── CheckIntervalPreference.java
│ │ │ ├── TimePreference.java
│ │ │ └── DurationPreferenceDialogFragment.java
│ │ │ ├── backup
│ │ │ ├── WorkTimeTrackerBackupAgentHelper.java
│ │ │ └── WorkTimeTrackerBackupManager.java
│ │ │ ├── AutomaticBackup.java
│ │ │ ├── ui
│ │ │ └── TargetTimeValidityCheck.java
│ │ │ ├── ShortcutReceiver.java
│ │ │ ├── DebugActivity.java
│ │ │ ├── UpgradeActivity.java
│ │ │ ├── editevent
│ │ │ └── TimeTextViewController.java
│ │ │ ├── MessageActivity.java
│ │ │ └── report
│ │ │ ├── ReportPreviewActivity.java
│ │ │ ├── TaskAndHint.java
│ │ │ ├── TimeSumsHolder.java
│ │ │ └── TargetDaysHolder.java
│ ├── test
│ │ └── java
│ │ │ └── org
│ │ │ └── zephyrsoft
│ │ │ └── trackworktime
│ │ │ ├── util
│ │ │ └── DateTimeUtilTest.java
│ │ │ ├── options
│ │ │ └── DataTypeTest.java
│ │ │ └── model
│ │ │ └── TimeSumTest.java
│ └── androidTest
│ │ └── java
│ │ └── org
│ │ └── zephyrsoft
│ │ └── trackworktime
│ │ └── ClearAppDataRule.java
└── lint.xml
├── gradle.properties
├── .woodpecker
├── renovate.yaml
└── build+release.yaml
└── gradlew.bat
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/metadata/en-US/title.txt:
--------------------------------------------------------------------------------
1 | Track Work Time
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | local.properties
4 | .idea
5 | .DS_Store
6 | build
7 | /captures
8 |
--------------------------------------------------------------------------------
/metadata/en-US/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/metadata/en-US/images/icon.png
--------------------------------------------------------------------------------
/metadata/en-US/short_description.txt:
--------------------------------------------------------------------------------
1 | Record your work time. Categorize it with different tasks. Generate reports.
2 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/metadata/en-US/images/icon-raw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/metadata/en-US/images/icon-raw.png
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/backup_ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable/backup_ok.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_play.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_stop.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_play.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_stop.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_play.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_stop.png
--------------------------------------------------------------------------------
/app/src/main/res/xml/shortcuts.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_play.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_stop.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_play.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_stop.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_play.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_stop.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/backup_not_ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable/backup_not_ok.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable/widget_preview.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/metadata/en-US/images/phoneScreenshots/1.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/metadata/en-US/images/phoneScreenshots/2.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/metadata/en-US/images/phoneScreenshots/3.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/metadata/en-US/images/phoneScreenshots/4.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/metadata/en-US/images/phoneScreenshots/5.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/metadata/en-US/images/phoneScreenshots/6.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/metadata/en-US/images/phoneScreenshots/7.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/metadata/en-US/images/phoneScreenshots/8.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/metadata/en-US/images/phoneScreenshots/9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_menu_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_menu_edit.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_mark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_menu_mark.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_menu_star.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_menu_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_menu_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_menu_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_menu_edit.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_menu_mark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_menu_mark.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_menu_star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_menu_star.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_menu_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_menu_edit.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_mark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_menu_mark.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_menu_star.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_add.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/raw/about.txt:
--------------------------------------------------------------------------------
1 |
2 |
{0}
3 |
4 | Version {1}
5 |
6 | Feedback (in English or German):
7 | {2}
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_agenda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_menu_agenda.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_compass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_menu_compass.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_menu_delete.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_menu_forward.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_revert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_menu_revert.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_notification.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_menu_agenda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_menu_agenda.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_menu_compass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_menu_compass.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_menu_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_menu_delete.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_menu_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_menu_forward.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_menu_revert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_menu_revert.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_notification.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_agenda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_menu_agenda.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_compass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_menu_compass.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_menu_delete.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_menu_forward.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_revert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_menu_revert.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_notification.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_agenda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_agenda.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_delete.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_edit.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_mark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_mark.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_revert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_revert.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_star.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_menu_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_menu_edit.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_mark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_menu_mark.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_menu_star.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_menu_add.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_menu_edit.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_mark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_menu_mark.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_menu_star.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/xml/provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_compass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_compass.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_forward.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_notification.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_agenda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_menu_agenda.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_compass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_menu_compass.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_menu_delete.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_menu_forward.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_revert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_menu_revert.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_notification.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_agenda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_menu_agenda.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_menu_delete.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_revert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_menu_revert.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_info_details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_menu_info_details.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_mylocation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_menu_mylocation.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_preferences.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_menu_preferences.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_sort_by_size.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_menu_sort_by_size.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_menu_info_details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_menu_info_details.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_menu_mylocation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_menu_mylocation.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_menu_preferences.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_menu_preferences.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_menu_sort_by_size.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_menu_sort_by_size.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_info_details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_menu_info_details.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_mylocation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_menu_mylocation.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_preferences.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_menu_preferences.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_sort_by_size.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_menu_sort_by_size.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_mylocation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_mylocation.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_preferences.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_preferences.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_mylocation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_menu_mylocation.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_compass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_menu_compass.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_menu_forward.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_notification.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_info_details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_info_details.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_sort_by_size.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_sort_by_size.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_info_details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_menu_info_details.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_preferences.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_menu_preferences.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_sort_by_size.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_menu_sort_by_size.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_mylocation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_menu_mylocation.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_preferences.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_menu_preferences.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_info_details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_menu_info_details.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_sort_by_size.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_menu_sort_by_size.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_menu_close_clear_cancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-hdpi/ic_menu_close_clear_cancel.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_menu_close_clear_cancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-ldpi/ic_menu_close_clear_cancel.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_menu_close_clear_cancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-mdpi/ic_menu_close_clear_cancel.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_menu_close_clear_cancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xhdpi/ic_menu_close_clear_cancel.png
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_menu_close_clear_cancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxhdpi/ic_menu_close_clear_cancel.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_menu_close_clear_cancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathisdt/trackworktime/HEAD/app/src/main/res/drawable-xxxhdpi/ic_menu_close_clear_cancel.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/side_nav_bar.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_navigate_arrow_left.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/item_drawable.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/widget_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/list_context_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/app/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
3 | distributionPath=wrapper/dists
4 | zipStorePath=wrapper/dists
5 | distributionSha256Sum=72f44c9f8ebcb1af43838f45ee5c4aa9c5444898b3468ab3f4af7b6076c5bc3f
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_calendar_recenter_left.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tasks_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_calendar_recenter_right.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_navigate_arrow_right.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values-sw360dp/preference.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | 0dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_spinner.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-sizes.txt:
--------------------------------------------------------------------------------
1 |
2 | 36x36 (0.75x) for low-density (ldpi)
3 | 48x48 (1.0x baseline) for medium-density (mdpi)
4 | 72x72 (1.5x) for high-density (hdpi)
5 | 96x96 (2.0x) for extra-high-density (xhdpi)
6 | 144x144 (3.0x) for extra-extra-high-density (xxhdpi)
7 | 192x192 (4.0x) for extra-extra-extra-high-density (xxxhdpi)
8 |
9 | Source: https://developer.android.com/training/multiscreen/screendensities
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_download.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/eventlist/BaseEventItem.java:
--------------------------------------------------------------------------------
1 | package org.zephyrsoft.trackworktime.eventlist;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | public abstract class BaseEventItem {
6 |
7 | public abstract int getId();
8 | public abstract boolean isSameContentAs(@NonNull BaseEventItem other);
9 |
10 | public boolean isSameIdAs(@NonNull BaseEventItem other) {
11 | return getId() == other.getId();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/res/xml-v31/widget_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/widget_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/options_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/message.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | app_title=Track Work Time
2 |
3 | # customize to create multiple versions of the app to install in parallel
4 | app_suffix=
5 |
6 | # use appropriate AndroidX library instead of a Support Library
7 | android.useAndroidX=true
8 | # automatic migrating of third-party libraries to AndroidX not needed
9 | android.enableJetifier=false
10 | # Github Actions don't reserve enough memory without this:
11 | org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m
12 | # generate transitive resource classes
13 | android.nonTransitiveRClass=false
14 | # keep resource IDs final
15 | android.nonFinalResIds=false
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_box_closed.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_separator.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/eventlist/EventSeparatorViewHolder.java:
--------------------------------------------------------------------------------
1 | package org.zephyrsoft.trackworktime.eventlist;
2 |
3 | import androidx.recyclerview.widget.RecyclerView.ViewHolder;
4 |
5 | import org.zephyrsoft.trackworktime.databinding.ListItemSeparatorBinding;
6 |
7 | public class EventSeparatorViewHolder extends ViewHolder {
8 | private final ListItemSeparatorBinding binding;
9 |
10 | public EventSeparatorViewHolder(ListItemSeparatorBinding binding) {
11 | super(binding.getRoot());
12 | this.binding = binding;
13 | }
14 |
15 | public void bind(EventSeparatorItem item) {
16 | binding.title.setText(item.getTitle());
17 | }
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_inactive.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 16dp
6 | 32dp
7 | 8dp
8 | 176dp
9 | 16dp
10 | 8dp
11 | 6dp
12 | 2dp
13 |
14 | 5dp
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_box_open.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_timezone_select.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
11 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/eventlist/EventSeparatorItem.java:
--------------------------------------------------------------------------------
1 | package org.zephyrsoft.trackworktime.eventlist;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | public class EventSeparatorItem extends BaseEventItem {
6 |
7 | private final int id;
8 | private final String caption;
9 |
10 | @NonNull
11 | public String getTitle() {
12 | return caption;
13 | }
14 |
15 | @Override
16 | public int getId() {
17 | return id;
18 | }
19 |
20 | public EventSeparatorItem(@NonNull String caption) {
21 | this.id = caption.hashCode();
22 | this.caption = caption;
23 | }
24 |
25 | @Override
26 | public boolean isSameContentAs(@NonNull BaseEventItem other) {
27 | if (!(other instanceof EventSeparatorItem)) {
28 | return false;
29 | }
30 | return getId() == other.getId();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/util/Updatable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.util;
17 |
18 | /**
19 | * Something that can be updated.
20 | */
21 | public interface Updatable {
22 | void update();
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/database/MigrationCallback.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.database;
17 |
18 | public interface MigrationCallback {
19 | void onProgressUpdate(int value);
20 |
21 | void migrationDone();
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/res/xml-v25/shortcuts.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
15 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/.woodpecker/renovate.yaml:
--------------------------------------------------------------------------------
1 | when:
2 | - event: [ cron ]
3 |
4 | clone:
5 | - name: clone
6 | image: woodpeckerci/plugin-git
7 | settings:
8 | depth: 0
9 | partial: false
10 | recursive: true
11 |
12 | steps:
13 | - name: renovate
14 | when:
15 | - event: cron
16 | cron: "renovate" # a cron with this name has to exist in the Woodpecker repo, e.g. with expression "30 3 * * *"
17 | depends_on: []
18 | image: renovate/renovate
19 | commands: |
20 | renovate $${CI_REPO}
21 | environment:
22 | RENOVATE_PLATFORM: forgejo
23 | RENOVATE_ENDPOINT: https://codeberg.org
24 | RENOVATE_ONBOARDING: false
25 | RENOVATE_REQUIRE_CONFIG: optional
26 | RENOVATE_AUTO_APPROVE: true
27 | RENOVATE_AUTOMERGE: true
28 | RENOVATE_AUTOMERGE_STRATEGY: fast-forward
29 | LOG_LEVEL: debug
30 | RENOVATE_TOKEN:
31 | from_secret: RENOVATE_TOKEN
32 | GITHUB_COM_TOKEN:
33 | from_secret: GITHUB_COM_TOKEN
34 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/model/PeriodEnum.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.model;
17 |
18 | /**
19 | * Range for which a {@link TimeSum} is valid / should be calculated.
20 | */
21 | public enum PeriodEnum {
22 | /** only one day */
23 | DAY,
24 | /** one week */
25 | WEEK,
26 | /** one month */
27 | MONTH,
28 | /** all time */
29 | ALL_TIME
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/util/StringExtractionMethod.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.util;
17 |
18 | /**
19 | * Represents a method how the {@link FlexibleArrayAdapter} extracts the text from an object.
20 | */
21 | public interface StringExtractionMethod {
22 |
23 | /**
24 | * Extract the text from the given object.
25 | */
26 | String extractText(T object);
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/util/FileUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.util;
17 |
18 | import java.io.IOException;
19 | import java.io.InputStream;
20 | import java.io.OutputStream;
21 |
22 | public class FileUtil {
23 |
24 | public static void copy(InputStream in, OutputStream out) throws IOException {
25 | byte[] buffer = new byte[1024];
26 | int read;
27 | while((read = in.read(buffer)) != -1) {
28 | out.write(buffer, 0, read);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/report_preview.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
17 |
18 |
21 |
22 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/location/LocationCallback.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.location;
17 |
18 | /**
19 | * Location-getting callback hook (as closures are not there yet).
20 | */
21 | public interface LocationCallback {
22 |
23 | /**
24 | * Called when the current location was found.
25 | */
26 | void callback(double latitude, double longitude, int tolerance);
27 |
28 | /**
29 | * Called when an error happens.
30 | */
31 | void error(Throwable t);
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/model/NightMode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.model;
17 |
18 | public enum NightMode {
19 | SYSTEM_DEFAULT(-1),
20 | LIGHT_MODE(1),
21 | DARK_MODE(2);
22 |
23 | /**
24 | * see {@code xml/strings.xml}, entry {@code nightModeValues}
25 | */
26 | private final int value;
27 |
28 | NightMode(int value) {
29 | this.value = value;
30 | }
31 |
32 | public int getValue() {
33 | return value;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/test/java/org/zephyrsoft/trackworktime/util/DateTimeUtilTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.util;
17 |
18 | import static com.google.common.truth.Truth.assertThat;
19 |
20 | import org.junit.Test;
21 |
22 | import java.time.LocalTime;
23 |
24 | public class DateTimeUtilTest {
25 |
26 | @Test
27 | public void parseTimeForToday() {
28 | LocalTime toTest = DateTimeUtil.parseTime("");
29 | assertThat(toTest.getHour()).isEqualTo(0);
30 | assertThat(toTest.getMinute()).isEqualTo(0);
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/util/GenericFileProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.util;
17 |
18 | import androidx.core.content.FileProvider;
19 |
20 | /**
21 | * Extend FileProvider to make sure our FileProvider doesn't conflict with any FileProviders declared
22 | * in imported dependencies as described at https://commonsware.com/blog/2017/06/27/fileprovider-libraries.html
23 | */
24 | public class GenericFileProvider extends FileProvider {
25 | // do nothing different than the extended class
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/test/java/org/zephyrsoft/trackworktime/options/DataTypeTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.options;
17 |
18 | import org.junit.Test;
19 |
20 | import static org.junit.Assert.assertTrue;
21 | import static org.zephyrsoft.trackworktime.options.DataType.HOUR_MINUTE;
22 |
23 | public class DataTypeTest {
24 |
25 | @Test
26 | public void hourMinute() {
27 | assertTrue(HOUR_MINUTE.validate("-1:55"));
28 | assertTrue(HOUR_MINUTE.validate("1:00"));
29 | assertTrue(HOUR_MINUTE.validate("1:29"));
30 | assertTrue(HOUR_MINUTE.validate("37:30"));
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/location/Result.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.location;
17 |
18 | /**
19 | * Result which gets returned by {@link LocationTracker#startTrackingByLocation(double, double, double, boolean)}.
20 | */
21 | public enum Result {
22 |
23 | /** successfully started the tracking */
24 | SUCCESS,
25 |
26 | /** could not start the tracking because is was already running */
27 | FAILURE_ALREADY_RUNNING,
28 |
29 | /** could not start the tracking, the app doesn't have the necessary rights */
30 | FAILURE_INSUFFICIENT_RIGHTS
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/model/Report.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.model;
17 |
18 | import androidx.annotation.NonNull;
19 |
20 | import java.io.Serializable;
21 |
22 | public final class Report implements Serializable {
23 | private final String name;
24 | private final String data;
25 |
26 | public Report(String name, String data) {
27 | this.name = name;
28 | this.data = data;
29 | }
30 |
31 | public @NonNull String getName() {
32 | return name;
33 | }
34 |
35 | public @NonNull String getData() {
36 | return data;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/model/TimeInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.model;
17 |
18 | public class TimeInfo {
19 | private long actual = 0;
20 | private long target = 0;
21 |
22 | public Long getActual() {
23 | return actual;
24 | }
25 |
26 | public void setActual(long actual) {
27 | this.actual = actual;
28 | }
29 |
30 | public Long getTarget() {
31 | return target;
32 | }
33 |
34 | public void setTarget(long target) {
35 | this.target = target;
36 | }
37 |
38 | public Long getBalance() {
39 | return actual - target;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #b2df3a
5 | #98c520
6 | #769a19
7 | #556e12
8 | #1C2406
9 | #111604
10 | #6334de
11 | #4d1fc0
12 | #2B1271
13 | #d0d0d0
14 | #DB4A4A
15 | #800000
16 | #000000
17 | #ffffff
18 | #a0a0a0
19 | #303030
20 | #2b2b2b
21 | #ffffff
22 | #4c4b4d
23 | #ff444444
24 | #5CFF16
25 | #00FFC4
26 | #FFD603
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/location/CoordinateUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.location;
17 |
18 | import java.math.BigDecimal;
19 |
20 | /**
21 | * Helper for handling geo-coordinates.
22 | */
23 | public class CoordinateUtil {
24 |
25 | /**
26 | * Round a coordinate with arbitrary precision to a value that makes sense.
27 | */
28 | public static String roundCoordinate(double coordinate) {
29 | BigDecimal ret = new BigDecimal(String.valueOf(coordinate));
30 | ret = ret.setScale(6, BigDecimal.ROUND_HALF_UP);
31 | return ret.toPlainString();
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/model/Unit.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.model;
17 |
18 | import android.content.Context;
19 |
20 | import org.zephyrsoft.trackworktime.R;
21 |
22 | public enum Unit {
23 | NULL(R.string.reportUnitNull),
24 | DAY(R.string.reportUnitDay),
25 | WEEK(R.string.reportUnitWeek),
26 | MONTH(R.string.reportUnitMonth),
27 | YEAR(R.string.reportUnitYear);
28 |
29 | private final int name;
30 |
31 | Unit(int name) {
32 | this.name = name;
33 | }
34 |
35 | public String getName(Context context) {
36 | return context.getString(name);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/model/Range.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.model;
17 |
18 | import android.content.Context;
19 |
20 | import org.zephyrsoft.trackworktime.R;
21 |
22 | public enum Range {
23 | LAST(R.string.reportRangeLast),
24 | CURRENT(R.string.reportRangeCurrent),
25 | LAST_AND_CURRENT(R.string.reportRangeLastAndCurrent),
26 | ALL_DATA(R.string.reportRangeAllData);
27 |
28 | private final int name;
29 |
30 | Range(int name) {
31 | this.name = name;
32 | }
33 |
34 | public String getName(Context context) {
35 | return context.getString(name);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/util/ForeignCall.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.util;
17 |
18 | import java.lang.annotation.ElementType;
19 | import java.lang.annotation.Retention;
20 | import java.lang.annotation.RetentionPolicy;
21 | import java.lang.annotation.Target;
22 |
23 | /**
24 | * Marks methods which are allowed to be called from another class. Primarily used in activities
25 | * (where methods normally are not called from other classes but only from the UI).
26 | */
27 | @Target(ElementType.METHOD)
28 | @Retention(RetentionPolicy.RUNTIME)
29 | public @interface ForeignCall {
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/Watchdog.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime;
17 |
18 | import android.content.BroadcastReceiver;
19 | import android.content.Context;
20 | import android.content.Intent;
21 |
22 | import org.zephyrsoft.trackworktime.location.LocationTrackerService;
23 |
24 | /**
25 | * Watchdog, e.g. for {@link LocationTrackerService}. It gets periodic intents scheduled by {@link Basics}.
26 | */
27 | public class Watchdog extends BroadcastReceiver {
28 |
29 | @Override
30 | public void onReceive(Context context, Intent intent) {
31 | Basics.get(context).periodicHook();
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/util/SeparatorIdentificationMethod.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.util;
17 |
18 | /**
19 | * Identifies the separators in a list. As this interface extends {@link StringExtractionMethod}, it can also extract
20 | * the text of the separators.
21 | */
22 | public interface SeparatorIdentificationMethod extends StringExtractionMethod {
23 |
24 | /**
25 | * Decides if the given object is a separator (and should be rendered as such).
26 | */
27 | boolean isSeparator(T object);
28 |
29 | @Override
30 | default String extractText(T object) {
31 | return "";
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/eventlist/EventViewHolder.java:
--------------------------------------------------------------------------------
1 | package org.zephyrsoft.trackworktime.eventlist;
2 |
3 | import androidx.recyclerview.selection.ItemDetailsLookup;
4 | import androidx.recyclerview.widget.RecyclerView.ViewHolder;
5 |
6 | import org.zephyrsoft.trackworktime.databinding.ListItemBinding;
7 | import org.zephyrsoft.trackworktime.model.Event;
8 |
9 | import java.util.function.Consumer;
10 |
11 | public class EventViewHolder extends ViewHolder {
12 | private final ListItemBinding binding;
13 |
14 | public EventViewHolder(ListItemBinding binding) {
15 | super(binding.getRoot());
16 | this.binding = binding;
17 | }
18 |
19 | public void bind(EventItem item, boolean isSelected, Consumer onClick) {
20 | binding.time.setText(item.getTime());
21 | binding.type.setText(item.getType());
22 | binding.task.setText(item.getTask());
23 | itemView.setActivated(isSelected);
24 | itemView.setOnClickListener(v -> onClick.accept(item.getEvent()));
25 | }
26 |
27 | public ItemDetailsLookup.ItemDetails getItemDetails() {
28 | return new ItemDetailsLookup.ItemDetails<>() {
29 | @Override
30 | public int getPosition() {
31 | return getBindingAdapterPosition();
32 | }
33 |
34 | @Override
35 | public Long getSelectionKey() {
36 | return getItemId();
37 | }
38 | };
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/BootCompletedReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime;
17 |
18 | import android.content.BroadcastReceiver;
19 | import android.content.Context;
20 | import android.content.Intent;
21 |
22 | import org.pmw.tinylog.Logger;
23 |
24 | /**
25 | * Gets intents when the device boot is completed and - if the app was moved to an external storage
26 | * - when the externalized app becomes available (again).
27 | */
28 | public class BootCompletedReceiver extends BroadcastReceiver {
29 |
30 | @Override
31 | public void onReceive(Context context, Intent intent) {
32 | Logger.debug("BootCompletedReceiver received intent: {}", intent);
33 | Basics.get(context).schedulePeriodicIntents();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_debug.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
18 |
19 |
25 |
26 |
27 |
33 |
34 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/org/zephyrsoft/trackworktime/ClearAppDataRule.java:
--------------------------------------------------------------------------------
1 | package org.zephyrsoft.trackworktime;
2 |
3 | import android.database.sqlite.SQLiteDatabase;
4 |
5 | import androidx.annotation.NonNull;
6 | import androidx.test.platform.app.InstrumentationRegistry;
7 |
8 | import org.junit.rules.TestRule;
9 | import org.junit.runner.Description;
10 | import org.junit.runners.model.Statement;
11 | import org.zephyrsoft.trackworktime.database.MySQLiteHelper;
12 |
13 | /**
14 | * Remove any events and targets from the database.
15 | */
16 | public class ClearAppDataRule implements TestRule {
17 |
18 | @NonNull
19 | @Override
20 | public final Statement apply(@NonNull final Statement base, @NonNull Description description) {
21 | return new ClearAppDataStatement(base);
22 | }
23 |
24 | private static class ClearAppDataStatement extends Statement {
25 |
26 | private final Statement base;
27 |
28 | public ClearAppDataStatement(Statement base) {
29 | this.base = base;
30 | }
31 |
32 | @Override
33 | public void evaluate() throws Throwable {
34 | MySQLiteHelper dbHelper = new MySQLiteHelper(InstrumentationRegistry.getInstrumentation().getTargetContext());
35 | SQLiteDatabase db = dbHelper.getWritableDatabase();
36 | db.delete(MySQLiteHelper.EVENT, null, null);
37 | db.delete(MySQLiteHelper.CACHE, null, null);
38 | db.delete(MySQLiteHelper.TARGET, null, null);
39 | db.close();
40 |
41 | base.evaluate();
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/model/Base.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.model;
17 |
18 | /**
19 | * Base class which all other data classes extend. Basic operations are defined here.
20 | */
21 | public abstract class Base {
22 |
23 | /**
24 | * Chainable compare operation.
25 | */
26 | @SuppressWarnings("null")
27 | protected int compare(Object attributeOfMe, Object attributeOfOther, int useIfEqual) {
28 | if (attributeOfMe == null && attributeOfOther == null) {
29 | return useIfEqual;
30 | } else if (attributeOfMe != null && attributeOfOther == null) {
31 | return 1;
32 | } else if (attributeOfMe == null && attributeOfOther != null) {
33 | return -1;
34 | } else {
35 | return attributeOfMe.toString().compareTo(attributeOfOther.toString());
36 | }
37 | }
38 |
39 | @Override
40 | public abstract String toString();
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_upgrade.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
17 |
23 |
24 |
31 |
32 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/location/TrackingMethod.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.location;
17 |
18 | import org.zephyrsoft.trackworktime.R;
19 | import org.zephyrsoft.trackworktime.timer.TimerManager;
20 |
21 | /**
22 | * Available methods of automatically tracking work time.
23 | */
24 | public enum TrackingMethod {
25 |
26 | LOCATION(R.string.keyClockedInByLocation, TimerManager.EventOrigin.LOCATION),
27 | WIFI(R.string.keyClockedInByWifi, TimerManager.EventOrigin.WIFI);
28 |
29 | private final int preferenceKeyId;
30 | private final TimerManager.EventOrigin source;
31 |
32 | TrackingMethod(int preferenceKeyId, TimerManager.EventOrigin source) {
33 | this.preferenceKeyId = preferenceKeyId;
34 | this.source = source;
35 | }
36 |
37 | public int getPreferenceKeyId() {
38 | return preferenceKeyId;
39 | }
40 |
41 | public TimerManager.EventOrigin getSource() {
42 | return source;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/about.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
16 |
17 |
24 |
25 |
26 |
27 |
28 |
33 |
34 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/weektimes/WeekStateLoaderFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.weektimes;
17 |
18 | import androidx.annotation.NonNull;
19 | import androidx.core.util.Consumer;
20 |
21 | import org.zephyrsoft.trackworktime.model.Week;
22 | import org.zephyrsoft.trackworktime.model.WeekState;
23 |
24 | public class WeekStateLoaderFactory {
25 |
26 | private final WeekStateCalculatorFactory weekStateCalculatorFactory;
27 |
28 | public WeekStateLoaderFactory(@NonNull WeekStateCalculatorFactory weekStateCalculatorFactory) {
29 | this.weekStateCalculatorFactory = weekStateCalculatorFactory;
30 | }
31 |
32 | public @NonNull WeekStateLoader create(@NonNull Week week,
33 | @NonNull Consumer onLoadedCallback) {
34 | WeekStateCalculator weekStateCalculator = weekStateCalculatorFactory.createForWeek(week);
35 | return new WeekStateLoader(weekStateCalculator, onLoadedCallback);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/options/Check.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.options;
17 |
18 | import android.content.SharedPreferences;
19 |
20 | /**
21 | * A check tests if a logical constraint holds. This constraint can involve multiple preferences.
22 | */
23 | public abstract class Check {
24 |
25 | private final String description;
26 |
27 | /**
28 | * Constructor
29 | */
30 | public Check(String description) {
31 | this.description = description;
32 | }
33 |
34 | /**
35 | * Gets the description.
36 | */
37 | public String getDescription() {
38 | return description;
39 | }
40 |
41 | /**
42 | * Does this check use the value of the specified preference?
43 | */
44 | public abstract boolean usesPreference(Key key);
45 |
46 | /**
47 | * Checks the constraint coded in this check.
48 | *
49 | * @return {@code true} if the constraint holds
50 | */
51 | public abstract boolean check(SharedPreferences prefs);
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/util/ThemeUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.util;
17 |
18 | import android.content.Context;
19 | import android.graphics.drawable.ColorDrawable;
20 | import android.util.TypedValue;
21 |
22 | import androidx.appcompat.app.ActionBar;
23 | import androidx.core.content.ContextCompat;
24 |
25 | import org.zephyrsoft.trackworktime.R;
26 |
27 | public class ThemeUtil {
28 | public static ActionBar styleActionBar(Context context, ActionBar actionBar) {
29 | if (actionBar != null) {
30 | actionBar.setDisplayHomeAsUpEnabled(true);
31 |
32 | TypedValue typedValue = new TypedValue();
33 | context.getTheme().resolveAttribute(R.attr.colorPrimaryVariant, typedValue, true);
34 | int color = ContextCompat.getColor(context, typedValue.resourceId);
35 | actionBar.setBackgroundDrawable(new ColorDrawable(color));
36 | }
37 | return actionBar;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/eventlist/EventItemMapper.java:
--------------------------------------------------------------------------------
1 | package org.zephyrsoft.trackworktime.eventlist;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import org.zephyrsoft.trackworktime.model.Event;
6 | import org.zephyrsoft.trackworktime.util.DateTimeUtil;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 | import java.util.Locale;
11 | import java.util.function.Function;
12 |
13 | public class EventItemMapper {
14 |
15 | private final Locale locale;
16 | private final Function eventTaskName;
17 |
18 | public EventItemMapper(
19 | @NonNull Locale locale,
20 | @NonNull Function eventTaskName
21 | ) {
22 | this.locale = locale;
23 | this.eventTaskName = eventTaskName;
24 | }
25 |
26 | public List map(List events) {
27 | List items = new ArrayList<>(events.size());
28 | Event prev = null;
29 | for (Event event : events) {
30 | if (prev == null || !isOnSameDay(prev, event)) {
31 | items.add(newEventSeparatorItem(event));
32 | }
33 | items.add(newEventItem(event));
34 | prev = event;
35 | }
36 | return items;
37 | }
38 |
39 | private static boolean isOnSameDay(Event e1, Event e2) {
40 | return e1.getDateTime().toLocalDate().isEqual(e2.getDateTime().toLocalDate());
41 | }
42 |
43 | private EventItem newEventItem(Event event) {
44 | return new EventItem(event, locale, eventTaskName.apply(event));
45 | }
46 |
47 | private EventSeparatorItem newEventSeparatorItem(Event event) {
48 | String caption = DateTimeUtil.formatLocalizedDayAndDate(event.getDateTime(), locale);
49 | return new EventSeparatorItem(caption);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
22 |
23 |
30 |
31 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/weektimes/WeekStateLoader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.weektimes;
17 |
18 | import android.os.AsyncTask;
19 |
20 | import androidx.annotation.NonNull;
21 | import androidx.core.util.Consumer;
22 |
23 | import org.zephyrsoft.trackworktime.model.WeekState;
24 |
25 | public class WeekStateLoader extends AsyncTask {
26 |
27 | private final WeekStateCalculator weekStateCalculator;
28 | private final Consumer onWeekStateLoaded;
29 |
30 | public WeekStateLoader(@NonNull WeekStateCalculator weekStateCalculator,
31 | @NonNull Consumer onWeekStateLoaded) {
32 | this.weekStateCalculator = weekStateCalculator;
33 | this.onWeekStateLoaded = onWeekStateLoaded;
34 | }
35 |
36 | @Override protected WeekState doInBackground(Void... voids) {
37 | return weekStateCalculator.calculateWeekState();
38 | }
39 |
40 | @Override protected void onPostExecute(WeekState weekState) {
41 | super.onPostExecute(weekState);
42 | onWeekStateLoaded.accept(weekState);
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/weektimes/WeekStateCalculatorFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.weektimes;
17 |
18 | import android.app.Activity;
19 | import android.content.SharedPreferences;
20 |
21 | import androidx.annotation.NonNull;
22 |
23 | import org.zephyrsoft.trackworktime.database.DAO;
24 | import org.zephyrsoft.trackworktime.model.Week;
25 | import org.zephyrsoft.trackworktime.timer.TimerManager;
26 |
27 | public class WeekStateCalculatorFactory {
28 |
29 | private final @NonNull Activity activity;
30 | private final @NonNull DAO dao;
31 | private final @NonNull TimerManager timerManager;
32 | private final @NonNull SharedPreferences preferences;
33 |
34 | public WeekStateCalculatorFactory(@NonNull Activity activity, @NonNull DAO dao,
35 | @NonNull TimerManager timerManager, @NonNull SharedPreferences preferences) {
36 | this.activity = activity;
37 | this.dao = dao;
38 | this.timerManager = timerManager;
39 | this.preferences = preferences;
40 | }
41 |
42 | public @NonNull WeekStateCalculator createForWeek(@NonNull Week week) {
43 | return new WeekStateCalculator(activity, dao, timerManager, preferences, week);
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/options/TimePreferenceDialogFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.options;
17 |
18 | import android.content.Context;
19 | import android.view.View;
20 | import android.widget.TimePicker;
21 |
22 | import androidx.preference.PreferenceDialogFragmentCompat;
23 |
24 | public class TimePreferenceDialogFragment extends PreferenceDialogFragmentCompat {
25 |
26 | private TimePicker timePicker;
27 |
28 | @Override
29 | protected View onCreateDialogView(Context context) {
30 | timePicker = new TimePicker(context);
31 | timePicker.setIs24HourView(true);
32 | return timePicker;
33 | }
34 |
35 | @Override
36 | protected void onBindDialogView(View view) {
37 | super.onBindDialogView(view);
38 |
39 | TimePreference pref = (TimePreference) getPreference();
40 |
41 | timePicker.setCurrentHour(pref.getHour());
42 | timePicker.setCurrentMinute(pref.getMinute());
43 | }
44 |
45 | @Override
46 | public void onDialogClosed(boolean positiveResult) {
47 | if (positiveResult) {
48 | TimePreference pref = (TimePreference) getPreference();
49 |
50 | pref.updateValue(timePicker.getCurrentHour(), timePicker.getCurrentMinute());
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/weektimes/WeekIndexConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.weektimes;
17 |
18 | import androidx.annotation.IntRange;
19 | import androidx.annotation.NonNull;
20 |
21 | import org.zephyrsoft.trackworktime.model.Week;
22 |
23 | import java.time.DayOfWeek;
24 | import java.time.LocalDate;
25 | import java.time.temporal.ChronoUnit;
26 |
27 | /**
28 | * Converts week-index to {@link Week} and vice versa, where week-index is number of weeks after epoch,
29 | * starting with 0.
30 | *
31 | * E.g. index of 0 means 1st week after epoch.
32 | */
33 | public class WeekIndexConverter {
34 | private static final LocalDate epochDate = LocalDate.ofEpochDay(0);
35 |
36 | public static @NonNull Week getWeekForIndex(@IntRange(from=0) int weekIndex) {
37 | if(weekIndex < 0) {
38 | throw new IllegalArgumentException("Week index should be positive");
39 | }
40 |
41 | return new Week(epochDate.plusWeeks(weekIndex));
42 | }
43 |
44 | public static @IntRange(from=0) int getIndexForDate(LocalDate date) {
45 | return (int) ChronoUnit.WEEKS.between(epochDate, date.with(DayOfWeek.MONDAY)) + 1;
46 | }
47 |
48 | public static @NonNull Week getWeekForDate(LocalDate date) {
49 | return new Week(date);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
22 |
23 |
28 |
29 |
34 |
35 |
36 |
37 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/util/PermissionCollector.java:
--------------------------------------------------------------------------------
1 | package org.zephyrsoft.trackworktime.util;
2 |
3 | import android.content.Context;
4 | import android.content.pm.PackageInfo;
5 | import android.content.pm.PackageManager;
6 |
7 | import androidx.annotation.NonNull;
8 |
9 | import com.google.auto.service.AutoService;
10 |
11 | import org.acra.builder.ReportBuilder;
12 | import org.acra.collector.Collector;
13 | import org.acra.collector.CollectorException;
14 | import org.acra.config.CoreConfiguration;
15 | import org.acra.data.CrashReportData;
16 | import org.pmw.tinylog.Logger;
17 |
18 | import java.util.ArrayList;
19 | import java.util.List;
20 |
21 | @AutoService(Collector.class)
22 | public class PermissionCollector implements Collector {
23 |
24 | @Override
25 | public void collect(@NonNull Context context, @NonNull CoreConfiguration coreConfiguration, @NonNull ReportBuilder reportBuilder, @NonNull CrashReportData crashReportData) throws CollectorException {
26 | String granted = String.join(", ", getGrantedPermissions(context));
27 | crashReportData.put("GRANTED_PERMISSIONS", granted);
28 | }
29 |
30 | private List getGrantedPermissions(Context context) {
31 | List granted = new ArrayList<>();
32 | try {
33 | PackageInfo pi = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
34 | for (int i = 0; i < pi.requestedPermissions.length; i++) {
35 | if ((pi.requestedPermissionsFlags[i] & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) {
36 | granted.add(pi.requestedPermissions[i]);
37 | }
38 | }
39 | } catch (Exception e) {
40 | Logger.warn(e, "could not determine the granted permissions");
41 | }
42 | return granted;
43 | }
44 |
45 | @Override
46 | public boolean enabled(@NonNull CoreConfiguration config) {
47 | return true;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/eventlist/EventItem.java:
--------------------------------------------------------------------------------
1 | package org.zephyrsoft.trackworktime.eventlist;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import org.zephyrsoft.trackworktime.model.Event;
6 | import org.zephyrsoft.trackworktime.model.TypeEnum;
7 | import org.zephyrsoft.trackworktime.util.DateTimeUtil;
8 |
9 | import java.time.OffsetDateTime;
10 | import java.util.Locale;
11 | import java.util.Optional;
12 |
13 | public class EventItem extends BaseEventItem {
14 |
15 | private final int id;
16 | private final Event event;
17 | private final String type;
18 | private final String time;
19 | private final String task;
20 |
21 | @NonNull
22 | public Event getEvent() {
23 | return event;
24 | }
25 |
26 | @NonNull
27 | public String getType() {
28 | return type;
29 | }
30 |
31 | @NonNull
32 | public String getTask() {
33 | return task;
34 | }
35 |
36 | @NonNull
37 | public String getTime() {
38 | return time;
39 | }
40 |
41 | @Override
42 | public int getId() {
43 | return this.id;
44 | }
45 |
46 | @Override
47 | public boolean isSameContentAs(@NonNull BaseEventItem other) {
48 | if (!(other instanceof EventItem)) {
49 | return false;
50 | }
51 | Event otherEvent = ((EventItem) other).getEvent();
52 | return getEvent().equals(otherEvent);
53 | }
54 |
55 | public EventItem(@NonNull Event event, @NonNull Locale locale, @NonNull String task) {
56 | this.event = event;
57 | this.id = Optional.ofNullable(event.getId()).orElse(System.identityHashCode(event));
58 | this.type = formatType(event.getTypeEnum());
59 | this.time = formatTime(event.getTime(), locale);
60 | this.task = task;
61 | }
62 |
63 | private String formatTime(OffsetDateTime time, Locale locale) {
64 | return DateTimeUtil.formatLocalizedTime(time, locale);
65 | }
66 |
67 | private String formatType(TypeEnum type) {
68 | switch (type) {
69 | case CLOCK_IN:
70 | return "IN";
71 | case CLOCK_OUT:
72 | return "OUT";
73 | default:
74 | throw new IllegalStateException("unrecognized event type");
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/weektimes/WeekTimesViewHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.weektimes;
17 |
18 | import androidx.annotation.NonNull;
19 | import androidx.annotation.Nullable;
20 | import androidx.lifecycle.LiveData;
21 | import androidx.lifecycle.Observer;
22 | import androidx.recyclerview.widget.RecyclerView;
23 |
24 | import org.zephyrsoft.trackworktime.model.WeekState;
25 |
26 | import java.util.Objects;
27 |
28 | public class WeekTimesViewHolder extends RecyclerView.ViewHolder implements Observer {
29 |
30 | private final WeekTimesView weekTimesView;
31 | private @Nullable LiveData weekStateLiveData;
32 |
33 | public WeekTimesViewHolder(@NonNull WeekTimesView weekTimesView) {
34 | super(weekTimesView);
35 | this.weekTimesView = weekTimesView;
36 | }
37 |
38 | public void bind(@NonNull LiveData weekStateLiveData) {
39 | this.weekStateLiveData = weekStateLiveData;
40 | weekStateLiveData.observeForever(this);
41 | }
42 |
43 | @Override
44 | public void onChanged(WeekState weekState) {
45 | Objects.requireNonNull(weekState);
46 | weekTimesView.setWeekState(weekState);
47 | }
48 |
49 | public void recycle() {
50 | removeObserver();
51 | weekTimesView.clearWeekState();
52 | }
53 |
54 | private void removeObserver() {
55 | if(weekStateLiveData != null) {
56 | weekStateLiveData.removeObserver(this);
57 | weekStateLiveData = null;
58 | }
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
24 |
25 |
35 |
36 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/options/TimeZonePreference.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.options;
17 |
18 | import android.content.Context;
19 | import android.content.res.TypedArray;
20 | import android.util.AttributeSet;
21 |
22 | import androidx.preference.DialogPreference;
23 |
24 | import org.pmw.tinylog.Logger;
25 | import org.zephyrsoft.trackworktime.R;
26 |
27 | import java.time.ZoneId;
28 |
29 | public class TimeZonePreference extends DialogPreference {
30 |
31 | public TimeZonePreference(Context context, AttributeSet attrs) {
32 | super(context, attrs, R.attr.preferenceScreenStyle);
33 | }
34 |
35 | @Override
36 | protected Object onGetDefaultValue(TypedArray a, int index) {
37 | return a.getString(index);
38 | }
39 |
40 | @Override
41 | protected void onSetInitialValue(Object defaultValue) {
42 | String timeZone;
43 |
44 | if (defaultValue == null) {
45 | timeZone = getPersistedString(ZoneId.systemDefault().getId());
46 | } else {
47 | timeZone = getPersistedString(defaultValue.toString());
48 | }
49 |
50 | try {
51 | ZoneId.of(timeZone);
52 | } catch (Exception e) {
53 | timeZone = ZoneId.systemDefault().getId();
54 |
55 | Logger.error("Invalid time zone was reset to system default.");
56 | }
57 |
58 | setSummary(timeZone);
59 | }
60 |
61 | void updateValue(String value) {
62 | if (callChangeListener(value)) {
63 | if (persistString(value)) {
64 | setSummary(value);
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/backup/WorkTimeTrackerBackupAgentHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.backup;
17 |
18 | import android.app.backup.BackupAgentHelper;
19 | import android.app.backup.BackupDataOutput;
20 | import android.app.backup.SharedPreferencesBackupHelper;
21 | import android.os.ParcelFileDescriptor;
22 |
23 | public class WorkTimeTrackerBackupAgentHelper extends BackupAgentHelper {
24 | // A key to uniquely identify the set of backup data
25 | private static final String PREFS_BACKUP_KEY = "prefs";
26 | // A key to uniquely identify the set of backup data
27 | private static final String DB_BACKUP_KEY = "db";
28 |
29 | // Allocate a helper and add it to the backup agent
30 | @Override
31 | public void onCreate() {
32 | // The name of the SharedPreferences file
33 | final String prefs = getPackageName() + "_preferences"; // getPackageName() cannot be used in final
34 | SharedPreferencesBackupHelper prefsHelper = new SharedPreferencesBackupHelper(this, prefs) {
35 | @Override
36 | public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
37 | ParcelFileDescriptor newState) {
38 | if (new WorkTimeTrackerBackupManager(WorkTimeTrackerBackupAgentHelper.this).isEnabled()) {
39 | super.performBackup(oldState, data, newState);
40 | }
41 | }
42 | };
43 | addHelper(PREFS_BACKUP_KEY, prefsHelper);
44 |
45 | DbBackupHelper dbHelper = new DbBackupHelper(this);
46 | addHelper(DB_BACKUP_KEY, dbHelper);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/model/Week.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.model;
17 |
18 | import java.time.DayOfWeek;
19 | import java.time.LocalDate;
20 |
21 | /**
22 | * Data class for a week.
23 | */
24 | public class Week extends Base implements Comparable {
25 | private final LocalDate startDay;
26 |
27 | public Week(LocalDate date) {
28 | // TODO consider locale
29 | startDay = date.with(DayOfWeek.MONDAY);
30 | }
31 |
32 | public Week(long epochDay) {
33 | startDay = LocalDate.ofEpochDay(epochDay);
34 | }
35 |
36 | public LocalDate getStart() {
37 | return startDay;
38 | }
39 |
40 | public LocalDate getEnd() {
41 | // TODO consider locale
42 | return startDay.with(DayOfWeek.SUNDAY);
43 | }
44 |
45 | public long toEpochDay() {
46 | return startDay.toEpochDay();
47 | }
48 |
49 | public Week plusWeeks(long weeksToAdd) {
50 | return new Week(startDay.plusWeeks(weeksToAdd));
51 | }
52 |
53 | public boolean isInWeek(LocalDate date) {
54 | return !date.isBefore(startDay) && !date.isAfter(getEnd());
55 | }
56 |
57 | @Override
58 | public int compareTo(Week another) {
59 | //return compare(getStart(), another.getStart(), compare(getId(), another.getId(), 0));
60 | return compare(getStart(), another.getStart(), 0);
61 | }
62 |
63 | /**
64 | * This is used e.g. by an ArrayAdapter in a ListView and it is also useful for debugging.
65 | *
66 | * @see Base#toString()
67 | */
68 | @Override
69 | public String toString() {
70 | return startDay.toString();
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/options/DurationPreference.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.options;
17 |
18 | import android.content.Context;
19 | import android.content.res.TypedArray;
20 | import android.util.AttributeSet;
21 |
22 | import androidx.preference.DialogPreference;
23 |
24 | import org.zephyrsoft.trackworktime.R;
25 | import org.zephyrsoft.trackworktime.util.DateTimeUtil;
26 |
27 | public class DurationPreference extends DialogPreference {
28 | private String duration = "0:00";
29 |
30 | public DurationPreference(Context context, AttributeSet attrs) {
31 | super(context, attrs);
32 | }
33 |
34 | @Override
35 | protected Object onGetDefaultValue(TypedArray a, int index) {
36 | return a.getString(index);
37 | }
38 |
39 | @Override
40 | protected void onSetInitialValue(Object defaultValue) {
41 | String value;
42 |
43 | if (defaultValue == null) {
44 | value = getPersistedString("00:00");
45 | } else {
46 | value = getPersistedString(defaultValue.toString());
47 | }
48 |
49 | if (DateTimeUtil.isDurationValid(value)) {
50 | duration = value;
51 | updateSummary();
52 | }
53 | }
54 |
55 | private void updateSummary() {
56 | setSummary(String.format(getContext().getString(R.string.current_value), duration));
57 | }
58 |
59 | void updateValue(String value) {
60 | if (DateTimeUtil.isDurationValid(value) && callChangeListener(value)) {
61 | duration = value;
62 |
63 | if (persistString(value)) {
64 | updateSummary();
65 | }
66 | }
67 | }
68 |
69 | String getDuration() {
70 | return duration;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/AutomaticBackup.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime;
17 |
18 | import android.content.Context;
19 |
20 | import androidx.annotation.NonNull;
21 |
22 | import org.pmw.tinylog.Logger;
23 | import org.zephyrsoft.trackworktime.backup.BackupFileInfo;
24 | import org.zephyrsoft.trackworktime.util.BackupUtil;
25 |
26 | import java.util.concurrent.ExecutorService;
27 | import java.util.concurrent.Executors;
28 |
29 | public class AutomaticBackup {
30 |
31 | private final Context context;
32 | private final ExecutorService executor = Executors.newSingleThreadExecutor(r -> {
33 | Thread t = new Thread(r);
34 | t.setDaemon(true);
35 | return t;
36 | });
37 |
38 | public AutomaticBackup(@NonNull Context context) {
39 | this.context = context;
40 | }
41 |
42 | public void doAsynchronously() {
43 | executor.submit(this::doSynchronously);
44 | }
45 |
46 | private void doSynchronously() {
47 | try {
48 | if (!DocumentTreeStorage.hasValidDirectoryGrant(context)) {
49 | Logger.warn("automatic backup failed because no document tree access has been granted");
50 | return;
51 | }
52 | final BackupFileInfo info = BackupFileInfo.getBackupFiles(context, false, true);
53 |
54 | Logger.info("starting automatic backup");
55 | BackupUtil.doBackup(context, info);
56 | Logger.info("automatic backup done");
57 | } catch (Exception e) {
58 | Logger.warn(e, "error while doing automatic backup");
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/options/FlexiIntervalPreference.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.options;
17 |
18 | import android.content.Context;
19 | import android.util.AttributeSet;
20 |
21 | import androidx.preference.ListPreference;
22 |
23 | import org.zephyrsoft.trackworktime.model.FlexiReset;
24 |
25 | import java.util.ArrayList;
26 | import java.util.List;
27 |
28 | public class FlexiIntervalPreference extends ListPreference {
29 |
30 | public FlexiIntervalPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
31 | super(context, attrs, defStyleAttr, defStyleRes);
32 | initialize();
33 | }
34 |
35 | public FlexiIntervalPreference(Context context, AttributeSet attrs, int defStyleAttr) {
36 | super(context, attrs, defStyleAttr);
37 | initialize();
38 | }
39 |
40 | public FlexiIntervalPreference(Context context, AttributeSet attrs) {
41 | super(context, attrs);
42 | initialize();
43 | }
44 |
45 | public FlexiIntervalPreference(Context context) {
46 | super(context);
47 | initialize();
48 | }
49 |
50 | private void initialize() {
51 | setDefaultSelection();
52 | setEntries();
53 | }
54 |
55 | private void setDefaultSelection() {
56 | setDefaultValue(FlexiReset.NONE.name());
57 | }
58 |
59 | private void setEntries() {
60 | List values = new ArrayList<>();
61 | List names = new ArrayList<>();
62 | for(FlexiReset flexiReset : FlexiReset.values()) {
63 | String name = flexiReset.getFriendlyName(getContext());
64 | names.add(name);
65 | String value = flexiReset.name();
66 | values.add(value);
67 | }
68 | setEntryValues(values.toArray(new String[0]));
69 | setEntries(names.toArray(new String[0]));
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
24 |
25 |
30 |
31 |
36 |
37 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/model/CalcCacheEntry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.model;
17 |
18 | import org.zephyrsoft.trackworktime.database.DAO;
19 |
20 | import java.time.LocalDate;
21 |
22 | /**
23 | * Data class for an event.
24 | *
25 | * @see DAO
26 | */
27 | public class CalcCacheEntry extends Base implements Comparable {
28 | private LocalDate date = null;
29 | private Long worked = null;
30 | private Long target = null;
31 |
32 | public CalcCacheEntry() {
33 | // do nothing
34 | }
35 |
36 | public CalcCacheEntry(LocalDate date, Long worked, Long target) {
37 | this.date = date;
38 | this.worked = worked;
39 | this.target = target;
40 | }
41 |
42 | public Long getDateAsId() {
43 | return this.date.toEpochDay();
44 | }
45 |
46 | public LocalDate getDate() {
47 | return this.date;
48 | }
49 |
50 | public Long getWorked() {
51 | return worked;
52 | }
53 |
54 | public Long getTarget() {
55 | return target;
56 | }
57 |
58 | public void setDateFromId(Long id) {
59 | this.date = LocalDate.ofEpochDay(id);
60 | }
61 |
62 | public void setDate(LocalDate date) {
63 | this.date = date;
64 | }
65 |
66 | public void setWorked(Long worked) {
67 | this.worked = worked;
68 | }
69 |
70 | public void setTarget(Long target) {
71 | this.target = target;
72 | }
73 |
74 | @Override
75 | public int compareTo(CalcCacheEntry another) {
76 | return compare(getDate(), another.getDate(), compare(getDateAsId(), another.getDateAsId(), 0));
77 | }
78 |
79 | /**
80 | * This is used e.g. by an ArrayAdapter in a ListView and it is also useful for debugging.
81 | *
82 | * @see Base#toString()
83 | */
84 | @Override
85 | public String toString() {
86 | return date.toString() + " / " + getWorked() + " / " + getTarget();
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/model/TargetWrapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.model;
17 |
18 | import android.content.Context;
19 |
20 | import org.zephyrsoft.trackworktime.R;
21 |
22 | import java.time.LocalDate;
23 |
24 | /**
25 | * Getters are used via reflection!
26 | */
27 | public class TargetWrapper {
28 | private final Target wrapped;
29 |
30 | public TargetWrapper(Target wrapped) {
31 | this.wrapped = wrapped;
32 | }
33 |
34 | public LocalDate getDate() {
35 | return wrapped.getDate();
36 | }
37 |
38 | public static String getType(Target target, Context context) {
39 | TargetEnum type = TargetEnum.byValue(target.getType());
40 | if (type == TargetEnum.DAY_SET
41 | && target.getValue() != null
42 | && target.getValue() > 0) {
43 | return context.getString(R.string.targetTypeChangeTargetTime);
44 | } else if (type == TargetEnum.DAY_SET
45 | && (target.getValue() == null
46 | || target.getValue() == 0)) {
47 | return context.getString(R.string.targetTypeNonWorking);
48 | } else if (type == TargetEnum.DAY_GRANT) {
49 | return context.getString(R.string.targetTypeWorkingEqualsTarget);
50 | }
51 | return context.getString(R.string.targetTypeUnknown);
52 | }
53 |
54 | public String getType(Context context) {
55 | return getType(wrapped, context);
56 | }
57 |
58 | public Integer getValue() {
59 | return wrapped.getValue();
60 | }
61 |
62 | public String getComment() {
63 | return wrapped.getComment();
64 | }
65 |
66 | public Integer getId() {
67 | return wrapped.getId();
68 | }
69 |
70 | public Integer getType() {
71 | return wrapped.getType();
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
24 |
25 |
30 |
31 |
36 |
37 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/ui/TargetTimeValidityCheck.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.ui;
17 |
18 | import android.content.Context;
19 | import android.text.Editable;
20 | import android.text.TextWatcher;
21 | import android.widget.EditText;
22 |
23 | import androidx.core.util.Consumer;
24 |
25 | import org.zephyrsoft.trackworktime.R;
26 | import org.zephyrsoft.trackworktime.util.DateTimeUtil;
27 |
28 | public class TargetTimeValidityCheck implements TextWatcher {
29 |
30 | private EditText textfield;
31 | private Consumer validityListener;
32 | private Context context;
33 |
34 | public TargetTimeValidityCheck(EditText textfield, Consumer validityListener,
35 | Context context) {
36 | this.textfield = textfield;
37 | this.validityListener = validityListener;
38 | this.context = context;
39 | }
40 |
41 | @Override
42 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
43 | // nothing to do
44 | }
45 |
46 | @Override
47 | public void onTextChanged(CharSequence s, int start, int before, int count) {
48 | // nothing to do
49 | }
50 |
51 | @Override
52 | public void afterTextChanged(Editable text) {
53 | check(text.toString());
54 | }
55 |
56 | public void check() {
57 | check(textfield.getText().toString());
58 | }
59 |
60 | private void check(String text) {
61 | if (!textfield.isEnabled() || DateTimeUtil.isDurationValid(text)) {
62 | textfield.setError(null);
63 | validityListener.accept(Boolean.TRUE);
64 | } else {
65 | textfield.setError(context.getString(R.string.invalidTarget));
66 | validityListener.accept(Boolean.FALSE);
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/options/CheckIntervalPreference.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.options;
17 |
18 | import android.content.Context;
19 | import android.content.res.TypedArray;
20 | import android.util.AttributeSet;
21 |
22 | import androidx.preference.DialogPreference;
23 |
24 | import org.zephyrsoft.trackworktime.R;
25 |
26 | public class CheckIntervalPreference extends DialogPreference {
27 | private Integer number = 1;
28 |
29 | public CheckIntervalPreference(Context context, AttributeSet attrs) {
30 | super(context, attrs);
31 | }
32 |
33 | @Override
34 | protected Object onGetDefaultValue(TypedArray a, int index) {
35 | return a.getString(index);
36 | }
37 |
38 | @Override
39 | protected void onSetInitialValue(Object defaultValue) {
40 | int value;
41 |
42 | if (defaultValue == null) {
43 | value = Integer.parseInt(getPersistedString("1"));
44 | } else {
45 | value = Integer.parseInt(getPersistedString(defaultValue.toString()));
46 | }
47 |
48 | if (isValid(value)) {
49 | number = value;
50 | updateSummary();
51 | }
52 | }
53 |
54 | private void updateSummary() {
55 | setSummary(String.format(getContext().getString(R.string.current_value_minutes), number.toString()));
56 | }
57 |
58 | static boolean isValid(String str) {
59 | try {
60 | int i = Integer.parseInt(str);
61 | return isValid(i);
62 | } catch (NumberFormatException nfe) {
63 | return false;
64 | }
65 | }
66 |
67 | static boolean isValid(int i) {
68 | return i >= 1 && i <= 60;
69 | }
70 |
71 | void updateValue(String value) {
72 | if (isValid(value) && callChangeListener(value)) {
73 | number = Integer.valueOf(value);
74 |
75 | if (persistString(number.toString())) {
76 | updateSummary();
77 | }
78 | }
79 | }
80 |
81 | Integer getNumber() {
82 | return number;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
21 |
22 |
30 |
31 |
44 |
45 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_day.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
21 |
22 |
30 |
31 |
44 |
45 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_night.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
21 |
22 |
30 |
31 |
44 |
45 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/options/TimePreference.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.options;
17 |
18 | import android.content.Context;
19 | import android.content.res.TypedArray;
20 | import android.util.AttributeSet;
21 |
22 | import androidx.preference.DialogPreference;
23 |
24 | import org.zephyrsoft.trackworktime.R;
25 | import org.zephyrsoft.trackworktime.util.DateTimeUtil;
26 |
27 | import java.time.LocalTime;
28 | import java.time.format.DateTimeFormatter;
29 |
30 | public class TimePreference extends DialogPreference {
31 | private static final DateTimeFormatter LOCAL_TIME = DateTimeFormatter.ofPattern("HH:mm");
32 |
33 | private LocalTime time = LocalTime.MIN;
34 |
35 | public TimePreference(Context context, AttributeSet attrs) {
36 | super(context, attrs);
37 | }
38 |
39 | @Override
40 | protected Object onGetDefaultValue(TypedArray a, int index) {
41 | return a.getString(index);
42 | }
43 |
44 | @Override
45 | protected void onSetInitialValue(Object defaultValue) {
46 | String timeString = getPersistedString(null);
47 |
48 | if (timeString == null && defaultValue != null) {
49 | timeString = defaultValue.toString();
50 | }
51 |
52 | if (timeString != null) {
53 | time = LocalTime.parse(DateTimeUtil.refineTime(timeString));
54 | updateSummary();
55 | }
56 | }
57 |
58 | private void updateSummary() {
59 | setSummary(String.format(getContext().getString(R.string.current_value), time.format(LOCAL_TIME)));
60 | }
61 |
62 | void updateValue(int hour, int minute) {
63 | LocalTime newTime = LocalTime.of(hour,minute);
64 | String value = newTime.toString();
65 |
66 | if (callChangeListener(value)) {
67 | time = newTime;
68 |
69 | if (persistString(value)) {
70 | updateSummary();
71 | }
72 | }
73 | }
74 |
75 | int getHour() {
76 | return time.getHour();
77 | }
78 |
79 | int getMinute() {
80 | return time.getMinute();
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/ShortcutReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime;
17 |
18 | import android.app.Activity;
19 | import android.os.Bundle;
20 |
21 | import org.pmw.tinylog.Logger;
22 | import org.zephyrsoft.trackworktime.model.TypeEnum;
23 | import org.zephyrsoft.trackworktime.timer.TimerManager;
24 |
25 | import java.time.OffsetDateTime;
26 |
27 | /**
28 | * This technically is an activity but it only receives intents from shortcuts
29 | * and the directly exits again. No UI is ever shown.
30 | */
31 | public class ShortcutReceiver extends Activity {
32 |
33 | @Override
34 | protected void onCreate(Bundle savedInstanceState) {
35 | String action = getIntent().getAction();
36 | TimerManager timerManager = Basics.get(getApplication()).getTimerManager();
37 | if (Constants.CLOCK_IN_ACTION.equals(action)) {
38 | Logger.info("TRACKING: clock-in via shortcut");
39 | Integer taskId = ThirdPartyReceiver.getDefaultTaskId(this);
40 | timerManager.createEvent(OffsetDateTime.now(), taskId, TypeEnum.CLOCK_IN, null, TimerManager.EventOrigin.LAUNCHER_SHORTCUT);
41 | WorkTimeTrackerActivity instanceOrNull = WorkTimeTrackerActivity.getInstanceOrNull();
42 | if (instanceOrNull != null) {
43 | instanceOrNull.refreshView();
44 | }
45 | Widget.dispatchUpdateIntent(this);
46 | } else if (Constants.CLOCK_OUT_ACTION.equals(action)) {
47 | Logger.info("TRACKING: clock-out via shortcut");
48 | timerManager.createEvent(OffsetDateTime.now(), null, TypeEnum.CLOCK_OUT, null, TimerManager.EventOrigin.LAUNCHER_SHORTCUT);
49 | WorkTimeTrackerActivity instanceOrNull = WorkTimeTrackerActivity.getInstanceOrNull();
50 | if (instanceOrNull != null) {
51 | instanceOrNull.refreshView();
52 | }
53 | Widget.dispatchUpdateIntent(this);
54 | }
55 | finish();
56 | super.onCreate(savedInstanceState);
57 | }
58 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/DebugActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime;
17 |
18 | import android.content.Intent;
19 | import android.os.Bundle;
20 | import android.view.MenuItem;
21 | import android.widget.Toast;
22 |
23 | import androidx.annotation.NonNull;
24 | import androidx.appcompat.app.AppCompatActivity;
25 |
26 | import org.pmw.tinylog.Logger;
27 | import org.zephyrsoft.trackworktime.database.DAO;
28 | import org.zephyrsoft.trackworktime.databinding.ActivityDebugBinding;
29 | import org.zephyrsoft.trackworktime.util.ThemeUtil;
30 |
31 | import java.time.ZoneId;
32 |
33 | public class DebugActivity extends AppCompatActivity {
34 |
35 | @Override
36 | protected void onCreate(Bundle savedInstanceState) {
37 | super.onCreate(savedInstanceState);
38 |
39 | ActivityDebugBinding binding = ActivityDebugBinding.inflate(getLayoutInflater());
40 | setContentView(binding.getRoot());
41 |
42 | ThemeUtil.styleActionBar(this, getSupportActionBar());
43 |
44 | binding.timezone.setText(ZoneId.systemDefault().toString());
45 |
46 | binding.startUpgrade.setOnClickListener(v -> {
47 | Logger.debug("showing upgrade activity");
48 | Intent i = new Intent(this, UpgradeActivity.class);
49 | startActivity(i);
50 | });
51 |
52 | binding.resetCache.setOnClickListener(v -> {
53 | Logger.debug("Deleting cache...");
54 |
55 | Basics basics = Basics.get(this);
56 | DAO dao = basics.getDao();
57 |
58 | dao.deleteCacheFrom(null);
59 | dao.close();
60 |
61 | Toast.makeText(this, getString(R.string.cacheDeleted), Toast.LENGTH_LONG).show();
62 | });
63 | }
64 |
65 | @Override
66 | public boolean onOptionsItemSelected(@NonNull MenuItem item) {
67 | if (item.getItemId() == android.R.id.home) {
68 | finish();
69 | return true;
70 | }
71 | throw new IllegalArgumentException("options menu: unknown item selected");
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/UpgradeActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime;
17 |
18 | import android.os.Build;
19 | import android.os.Bundle;
20 | import android.text.Html;
21 | import android.view.View;
22 | import android.widget.TextView;
23 | import android.widget.Toast;
24 |
25 | import androidx.appcompat.app.AppCompatActivity;
26 |
27 | import org.zephyrsoft.trackworktime.database.DAO;
28 | import org.zephyrsoft.trackworktime.database.MigrationCallback;
29 | import org.zephyrsoft.trackworktime.databinding.ActivityUpgradeBinding;
30 |
31 | public class UpgradeActivity extends AppCompatActivity implements MigrationCallback {
32 |
33 | private ActivityUpgradeBinding binding;
34 |
35 | @Override
36 | protected void onCreate(Bundle savedInstanceState) {
37 | super.onCreate(savedInstanceState);
38 |
39 | binding = ActivityUpgradeBinding.inflate(getLayoutInflater());
40 | setContentView(binding.getRoot());
41 |
42 | binding.migrationProgress.setVisibility(View.GONE);
43 |
44 | TextView upgradeText = binding.textUpgrade;
45 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
46 | upgradeText.setText(Html.fromHtml(getString(R.string.upgradeText), Html.FROM_HTML_MODE_COMPACT));
47 | } else {
48 | upgradeText.setText(Html.fromHtml(getString(R.string.upgradeText)));
49 | }
50 |
51 | binding.startMigration.setOnClickListener(v -> {
52 | // show progress bar
53 | binding.startMigration.setVisibility(View.GONE);
54 | binding.migrationProgress.setVisibility(View.VISIBLE);
55 |
56 | // save home time zone
57 | Basics basics = Basics.get(this);
58 | basics.setHomeTimeZone(binding.timeZonePicker.getZoneId());
59 |
60 | // start migration
61 | DAO dao = basics.getDao();
62 | dao.migrateEventsToV2(binding.timeZonePicker.getZoneId(), this);
63 | });
64 | }
65 |
66 | @Override
67 | public void onProgressUpdate(int value) {
68 | binding.migrationProgress.setProgress(value);
69 | }
70 |
71 | @Override
72 | public void migrationDone() {
73 | Toast.makeText(this, getString(R.string.databaseMigrationSuccess), Toast.LENGTH_LONG).show();
74 | finish();
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/model/WeekState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.model;
17 |
18 | import androidx.annotation.NonNull;
19 |
20 | import java.time.DayOfWeek;
21 |
22 | public class WeekState {
23 |
24 | public enum HighlightType {
25 | NONE,
26 | REGULAR_FREE,
27 | FREE,
28 | CHANGED_TARGET_TIME
29 | }
30 |
31 | public static class DayRowState {
32 | public String label = "";
33 | public HighlightType labelHighlighted = HighlightType.NONE;
34 | public String in = "";
35 | public String out = "";
36 | public String worked = "";
37 | public String workedDecimal = "";
38 | public String flexi = "";
39 | public String flexiDecimal = "";
40 |
41 | public boolean highlighted = false;
42 |
43 | @NonNull @Override
44 | public String toString() {
45 | return "values: " + label + ", " + in + ", " + out + ", " + worked + ", " + flexi
46 | + ", highlighted: " + highlighted;
47 | }
48 | }
49 |
50 | public static class SummaryRowState {
51 | public String label = "";
52 | public String worked = "";
53 | public String workedDecimal = "";
54 | public String flexi = "";
55 | public String flexiDecimal = "";
56 |
57 | @NonNull @Override
58 | public String toString() {
59 | return "values: " + label + ", " + worked + ", " + flexi;
60 | }
61 | }
62 |
63 | public String topLeftCorner = "";
64 | public final SummaryRowState totals = new SummaryRowState();
65 |
66 | private final DayRowState[] dayRowStates = {
67 | new DayRowState(), new DayRowState(), new DayRowState(), new DayRowState(),
68 | new DayRowState(), new DayRowState(), new DayRowState()
69 | };
70 |
71 | public DayRowState getRowForDay(DayOfWeek dayOfWeek) {
72 | return dayRowStates[dayOfWeek.ordinal()];
73 | }
74 |
75 | @NonNull @Override
76 | public String toString() {
77 | StringBuilder sb = new StringBuilder();
78 | sb.append(topLeftCorner); sb.append("\n");
79 |
80 | for (DayOfWeek day : DayOfWeek.values()) {
81 | sb.append(getRowForDay(day).toString());
82 | sb.append("\n");
83 | }
84 |
85 | sb.append(totals); sb.append("\n");
86 |
87 | return sb.toString();
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/backup/WorkTimeTrackerBackupManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.backup;
17 |
18 | import android.app.backup.BackupManager;
19 | import android.content.Context;
20 | import android.content.SharedPreferences;
21 | import android.content.SharedPreferences.Editor;
22 | import android.preference.PreferenceManager;
23 |
24 | import org.zephyrsoft.trackworktime.R;
25 |
26 | public class WorkTimeTrackerBackupManager {
27 | private final String prefKeyBackupEnabled;
28 | private static final String TIMESTAMP_BACKUP_KEY = "timestamp_backup";
29 | private final BackupManager backupManager;
30 | private final SharedPreferences timestampPrefs;
31 | private final SharedPreferences defaultPrefs;
32 | private boolean enabled;
33 |
34 | public WorkTimeTrackerBackupManager(final Context context) {
35 | prefKeyBackupEnabled = context.getText(R.string.keyBackupEnabled) + "";
36 | backupManager = new BackupManager(context);
37 | timestampPrefs = context.getSharedPreferences("timestampPrefs", Context.MODE_PRIVATE);
38 | defaultPrefs = PreferenceManager.getDefaultSharedPreferences(context);
39 | enabled = defaultPrefs.getBoolean(prefKeyBackupEnabled, false);
40 | }
41 |
42 | public void checkIfBackupEnabledChanged() {
43 | final boolean newValue = defaultPrefs.getBoolean(prefKeyBackupEnabled, false);
44 | if (enabled != newValue && backupManager != null) {
45 | // trigger if changed
46 | backupManager.dataChanged();
47 | }
48 | enabled = newValue;
49 | }
50 |
51 | public boolean isEnabled() {
52 | return enabled;
53 | }
54 |
55 | public void dataChanged() {
56 | if (enabled && backupManager != null) {
57 | backupManager.dataChanged();
58 | }
59 | }
60 |
61 | public void setLastBackupTimestamp(long lastBackupTimestamp) {
62 | final Editor editor = timestampPrefs.edit();
63 | // save value as string because there is no data type to hold long
64 | editor.putString(TIMESTAMP_BACKUP_KEY, lastBackupTimestamp + "");
65 | editor.commit();
66 | }
67 |
68 | public long getLastBackupTimestamp() {
69 | return Long.parseLong(timestampPrefs.getString(TIMESTAMP_BACKUP_KEY, "0"));
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/util/ExternalNotificationManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.util;
17 |
18 | import android.content.Context;
19 | import android.content.Intent;
20 | import android.content.SharedPreferences;
21 | import android.os.Vibrator;
22 |
23 | import org.json.JSONArray;
24 | import org.json.JSONObject;
25 | import org.pmw.tinylog.Logger;
26 | import org.zephyrsoft.trackworktime.R;
27 | import org.zephyrsoft.trackworktime.options.Key;
28 |
29 | import java.util.HashMap;
30 | import java.util.Map;
31 |
32 | /**
33 | * Manages vibration alarms.
34 | */
35 | public class ExternalNotificationManager {
36 |
37 | private final Context context;
38 | private final SharedPreferences preferences;
39 | private final Vibrator vibratorService;
40 |
41 | /**
42 | * Create the manager.
43 | */
44 | public ExternalNotificationManager(Context context, SharedPreferences preferences) {
45 | this.context = context;
46 | this.preferences = preferences;
47 | vibratorService = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
48 | }
49 |
50 | /**
51 | * Vibrate a specified pattern (once, do not repeat it).
52 | *
53 | * @see Vibrator#vibrate(long[], int)
54 | */
55 | public void vibrate(long[] pattern) {
56 | vibratorService.vibrate(pattern, -1);
57 | }
58 |
59 | public void notifyPebble(String message) {
60 | try {
61 | if (preferences.getBoolean(Key.NOTIFICATION_ON_PEBBLE.getName(), false)) {
62 | final Intent i = new Intent("com.getpebble.action.SEND_NOTIFICATION");
63 |
64 | final Map data = new HashMap<>();
65 | data.put("title", context.getString(R.string.app_name));
66 | data.put("body", message);
67 | final JSONObject jsonData = new JSONObject(data);
68 | final String notificationData = new JSONArray().put(jsonData).toString();
69 |
70 | i.putExtra("messageType", "PEBBLE_ALERT");
71 | i.putExtra("sender", "PebbleKit Android");
72 | i.putExtra("notificationData", notificationData);
73 | context.sendBroadcast(i);
74 | }
75 | } catch (Exception e) {
76 | Logger.warn(e, "problem while notifying via Pebble");
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/editevent/TimeTextViewController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.editevent;
17 |
18 | import android.app.TimePickerDialog;
19 | import android.content.Context;
20 | import android.text.format.DateFormat;
21 | import android.widget.TextView;
22 | import android.widget.TimePicker;
23 |
24 | import androidx.annotation.NonNull;
25 | import androidx.annotation.Nullable;
26 | import androidx.core.util.Consumer;
27 |
28 | import org.zephyrsoft.trackworktime.Basics;
29 | import org.zephyrsoft.trackworktime.util.DateTimeUtil;
30 |
31 | import java.time.LocalTime;
32 |
33 | public class TimeTextViewController {
34 |
35 | private final TextView view;
36 | private Consumer listener;
37 |
38 | @Nullable
39 | private LocalTime time;
40 |
41 | public void setTime(@Nullable LocalTime time) {
42 | String text = DateTimeUtil.formatLocalizedTime(time, Basics.get(view.getContext()).getLocale());
43 | view.setText(text);
44 | this.time = time;
45 |
46 | if (listener != null) {
47 | listener.accept(time);
48 | }
49 | }
50 |
51 | @Nullable
52 | public LocalTime getTime() {
53 | return time;
54 | }
55 |
56 | public void setListener(Consumer listener) {
57 | this.listener = listener;
58 | }
59 |
60 | public TimeTextViewController(@NonNull TextView view) {
61 | this.view = view;
62 | view.setOnClickListener(v -> showPicker());
63 | }
64 |
65 | private void showPicker() {
66 | createPicker().show();
67 | }
68 |
69 | private TimePickerDialog createPicker() {
70 | LocalTime time = getInitialTime();
71 | Context context = view.getContext();
72 | boolean is24Format = DateFormat.is24HourFormat(context);
73 | return new TimePickerDialog(
74 | context,
75 | this::onNewTimeSelected,
76 | time.getHour(),
77 | time.getMinute(),
78 | is24Format
79 | );
80 | }
81 |
82 | private LocalTime getInitialTime() {
83 | if(time == null) {
84 | return LocalTime.now();
85 | } else {
86 | return time;
87 | }
88 | }
89 |
90 | private void onNewTimeSelected(TimePicker view, int hourOfDay, int minute) {
91 | LocalTime time = LocalTime.of(hourOfDay, minute);
92 | setTime(time);
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/util/TinylogAndLogcatLogger.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.util;
17 |
18 | import android.util.Log;
19 |
20 | import org.acra.log.ACRALog;
21 | import org.pmw.tinylog.Logger;
22 |
23 | /**
24 | * ACRA logger for also collecting crash stack traces to the app's log file.
25 | */
26 | public class TinylogAndLogcatLogger implements ACRALog {
27 | @Override
28 | public int v(String tag, String msg) {
29 | Logger.trace(msg);
30 | return Log.v(tag, msg);
31 | }
32 | @Override
33 | public int v(String tag, String msg, Throwable tr) {
34 | Logger.trace(tr, msg);
35 | return Log.v(tag, msg, tr);
36 | }
37 | @Override
38 | public int d(String tag, String msg) {
39 | Logger.debug(msg);
40 | return Log.d(tag, msg);
41 | }
42 | @Override
43 | public int d(String tag, String msg, Throwable tr) {
44 | Logger.debug(tr, msg);
45 | return Log.d(tag, msg, tr);
46 | }
47 | @Override
48 | public int i(String tag, String msg) {
49 | Logger.info(msg);
50 | return Log.i(tag, msg);
51 | }
52 | @Override
53 | public int i(String tag, String msg, Throwable tr) {
54 | Logger.info(tr, msg);
55 | return Log.i(tag, msg, tr);
56 | }
57 | @Override
58 | public int w(String tag, String msg) {
59 | Logger.warn(msg);
60 | return Log.w(tag, msg);
61 | }
62 | @Override
63 | public int w(String tag, String msg, Throwable tr) {
64 | Logger.warn(tr, msg);
65 | return Log.w(tag, msg, tr);
66 | }
67 | @Override
68 | public int w(String tag, Throwable tr) {
69 | Logger.warn(tr);
70 | return Log.w(tag, tr);
71 | }
72 | @Override
73 | public int e(String tag, String msg) {
74 | Logger.error(msg);
75 | return Log.e(tag, msg);
76 | }
77 | @Override
78 | public int e(String tag, String msg, Throwable tr) {
79 | Logger.error(tr, msg);
80 | return Log.e(tag, msg, tr);
81 | }
82 | @Override
83 | public String getStackTraceString(Throwable tr) {
84 | return Log.getStackTraceString(tr);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/model/Target.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.model;
17 |
18 | import org.zephyrsoft.trackworktime.database.DAO;
19 |
20 | import java.time.LocalDate;
21 | import java.time.format.DateTimeFormatter;
22 |
23 | /**
24 | * Data class for an event.
25 | *
26 | * @see DAO
27 | */
28 | public class Target extends Base implements Comparable {
29 | private Integer id = null;
30 | private Integer type = null;
31 | private Integer value = null;
32 | private LocalDate date = null;
33 | private String comment = null;
34 |
35 | public Target() {
36 | // do nothing
37 | }
38 |
39 | public Target(Integer id, Integer type, Integer value, LocalDate date, String comment) {
40 | this.id = id;
41 | this.type = type;
42 | this.value = value;
43 | this.date = date;
44 | this.comment = comment;
45 | }
46 |
47 | public Integer getId() {
48 | return id;
49 | }
50 |
51 | public Integer getType() {
52 | return type;
53 | }
54 |
55 | public Integer getValue() {
56 | return value;
57 | }
58 |
59 | public LocalDate getDate() {
60 | return date;
61 | }
62 |
63 | public void setId(Integer id) {
64 | this.id = id;
65 | }
66 |
67 | public void setType(Integer type) {
68 | this.type = type;
69 | }
70 |
71 | public void setValue(Integer value) {
72 | this.value = value;
73 | }
74 |
75 | public void setDate(LocalDate date) {
76 | this.date = date;
77 | }
78 |
79 | public String getComment() {
80 | return comment;
81 | }
82 |
83 | public void setComment(String comment) {
84 | this.comment = comment;
85 | }
86 |
87 | @Override
88 | public int compareTo(Target another) {
89 | return compare(getDate(), another.getDate(), compare(getId(), another.getId(), 0));
90 | }
91 |
92 | /**
93 | * This is used e.g. by an ArrayAdapter in a ListView and it is also useful for debugging.
94 | *
95 | * @see Base#toString()
96 | */
97 | @Override
98 | public String toString() {
99 | return date.format(DateTimeFormatter.ISO_LOCAL_DATE) + " / " + TargetEnum.byValue(getType()).name() + " / " + getValue() + " / " + getComment();
100 | }
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/MessageActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime;
17 |
18 | import android.app.NotificationManager;
19 | import android.content.Context;
20 | import android.os.Bundle;
21 | import android.view.MenuItem;
22 | import android.view.View;
23 | import android.view.View.OnClickListener;
24 | import android.view.Window;
25 |
26 | import androidx.annotation.NonNull;
27 | import androidx.appcompat.app.AppCompatActivity;
28 |
29 | import org.zephyrsoft.trackworktime.databinding.MessageBinding;
30 | import org.zephyrsoft.trackworktime.util.ThemeUtil;
31 |
32 | /**
33 | * Activity for showing a message to the user.
34 | */
35 | public class MessageActivity extends AppCompatActivity implements OnClickListener {
36 |
37 | private MessageBinding binding;
38 | private int id = -1;
39 |
40 | @Override
41 | protected void onCreate(Bundle savedInstanceState) {
42 | super.onCreate(savedInstanceState);
43 | requestWindowFeature(Window.FEATURE_NO_TITLE);
44 |
45 | binding = MessageBinding.inflate(getLayoutInflater());
46 | setContentView(binding.getRoot());
47 |
48 | ThemeUtil.styleActionBar(this, getSupportActionBar());
49 |
50 | binding.message.setOnClickListener(this);
51 | }
52 |
53 | @Override
54 | protected void onResume() {
55 | super.onResume();
56 | String message = getIntent().getStringExtra(Constants.MESSAGE_EXTRA_KEY);
57 | id = getIntent().getIntExtra(Constants.ID_EXTRA_KEY, -1);
58 |
59 | binding.message.setText(message);
60 | }
61 |
62 | @Override
63 | public void onClick(View view) {
64 | closeNotificationAndDialog();
65 | }
66 |
67 | @Override
68 | public void onBackPressed() {
69 | closeNotificationAndDialog();
70 | }
71 |
72 | private void closeNotificationAndDialog() {
73 | if (id != -1) {
74 | NotificationManager service = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
75 | service.cancel(id);
76 | }
77 | finish();
78 | }
79 |
80 | @Override
81 | public boolean onOptionsItemSelected(@NonNull MenuItem item) {
82 | if (item.getItemId() == android.R.id.home) {
83 | closeNotificationAndDialog();
84 | return true;
85 | }
86 | throw new IllegalArgumentException("options menu: unknown item selected");
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/report/ReportPreviewActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.report;
17 |
18 | import android.content.Context;
19 | import android.content.Intent;
20 | import android.os.Bundle;
21 | import android.view.MenuItem;
22 |
23 | import androidx.annotation.NonNull;
24 | import androidx.annotation.Nullable;
25 | import androidx.appcompat.app.ActionBar;
26 | import androidx.appcompat.app.AppCompatActivity;
27 | import androidx.databinding.DataBindingUtil;
28 |
29 | import org.zephyrsoft.trackworktime.R;
30 | import org.zephyrsoft.trackworktime.databinding.ReportPreviewBinding;
31 | import org.zephyrsoft.trackworktime.model.Report;
32 | import org.zephyrsoft.trackworktime.util.ThemeUtil;
33 |
34 | public class ReportPreviewActivity extends AppCompatActivity {
35 |
36 | private static final String EXTRA_REPORT = "report";
37 |
38 | private ReportPreviewBinding binding;
39 |
40 | public static Intent createIntent(@NonNull Context context, @NonNull Report report) {
41 | Intent intent = new Intent(context, ReportPreviewActivity.class);
42 | intent.putExtra(EXTRA_REPORT, report);
43 | return intent;
44 | }
45 |
46 | @Override
47 | protected void onCreate(@Nullable Bundle savedInstanceState) {
48 | super.onCreate(savedInstanceState);
49 | binding = DataBindingUtil.setContentView(this, R.layout.report_preview);
50 | setTitle();
51 |
52 | Report report = getReport();
53 | loadReport(report);
54 | }
55 |
56 | private Report getReport() {
57 | return (Report) getIntent().getSerializableExtra(EXTRA_REPORT);
58 | }
59 |
60 | private void loadReport(Report report) {
61 | setContent(report.getData());
62 | }
63 |
64 | private void setTitle() {
65 | ActionBar bar = ThemeUtil.styleActionBar(this, getSupportActionBar());
66 | if (bar != null) {
67 | bar.setTitle(R.string.report_preview);
68 | }
69 |
70 | }
71 |
72 | private void setContent(String content) {
73 | binding.setData(content);
74 | }
75 |
76 | @Override
77 | public boolean onOptionsItemSelected(@NonNull MenuItem item) {
78 | switch (item.getItemId()) {
79 | case android.R.id.home:
80 | finish();
81 | return true;
82 | default:
83 | throw new IllegalArgumentException("options menu: unknown item selected");
84 | }
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/.woodpecker/build+release.yaml:
--------------------------------------------------------------------------------
1 | when:
2 | - event: [push, manual]
3 |
4 | clone:
5 | - name: clone
6 | image: woodpeckerci/plugin-git
7 | settings:
8 | depth: 0
9 | partial: false
10 | recursive: true
11 |
12 | steps:
13 | - name: mirror to Github
14 | when:
15 | - event: [ push, manual ]
16 | branch: [ master, main ]
17 | depends_on: []
18 | image: codeberg.org/mathisdt/buildhelper:latest
19 | pull: true
20 | environment:
21 | TOKEN_GITHUB:
22 | from_secret: TOKEN_GITHUB
23 | commands: |
24 | git remote add github https://mathisdt:$TOKEN_GITHUB@github.com/mathisdt/$CI_REPO_NAME.git
25 | git push github
26 | - name: build
27 | when:
28 | - event: [ push, manual ]
29 | depends_on: []
30 | image: eclipse-temurin:25-jdk
31 | pull: true
32 | commands: |
33 | echo "installing packages..."
34 | apt-get update >/dev/null 2>&1
35 | apt-get -y install curl unzip wget >/dev/null 2>&1
36 | echo "done installing packages"
37 | echo "setting up Android SDK..."
38 | export ANDROID_SDK_ROOT="/sdk"
39 | export ANDROID_HOME="$ANDROID_SDK_ROOT"
40 | export PATH="$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools"
41 | # download URL from https://developer.android.com/studio?hl=en#command-line-tools-only:
42 | curl -s https://dl.google.com/android/repository/commandlinetools-linux-13114758_latest.zip -o /cmdline-tools.zip
43 | mkdir -p $ANDROID_SDK_ROOT/cmdline-tools
44 | unzip -q /cmdline-tools.zip -d $ANDROID_SDK_ROOT/cmdline-tools/
45 | mv $ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools $ANDROID_SDK_ROOT/cmdline-tools/latest
46 | rm -f /cmdline-tools.zip
47 | mkdir -p $ANDROID_SDK_ROOT/licenses
48 | echo "8933bad161af4178b1185d1a37fbf41ea5269c55\nd56f5187479451eabf01fb78af6dfcb131a6481e\n24333f8a63b6825ea9c5514f83c2829b004d1fee" > $ANDROID_SDK_ROOT/licenses/android-sdk-license
49 | echo "84831b9409646a918e30573bab4c9c91346d8abd\n504667f4c0de7af1a06de9f4b1727b84351f2910" > $ANDROID_SDK_ROOT/licenses/android-sdk-preview-license
50 | yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses >/dev/null
51 | # has to match the required version in app/build.gradle (platform AND build-tools):
52 | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager "platform-tools" "platforms;android-36" "build-tools;36.0.0" >/dev/null
53 | echo "done setting up Android SDK"
54 | TZ=Europe/Berlin ./gradlew clean test
55 | TZ=Europe/Berlin ./gradlew assemble
56 | - name: release on Codeberg
57 | when:
58 | - event: manual
59 | branch: [ master, main ]
60 | depends_on: [ build ]
61 | image: codeberg.org/mathisdt/releaseplugin:latest
62 | pull: true
63 | settings:
64 | TAG_PATTERN: "^v"
65 | RELEASE_NOTES: "see changelog: https://zephyrsoft.org/trackworktime/history"
66 | PATTERN_TO_RELEASE: 'app/build/outputs/apk/release/*.apk'
67 | TOKEN:
68 | from_secret: TOKEN_REPO_READWRITE
69 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/report/TaskAndHint.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.report;
17 |
18 | import org.zephyrsoft.trackworktime.model.Base;
19 | import org.zephyrsoft.trackworktime.model.Task;
20 |
21 | import java.util.Objects;
22 |
23 | /**
24 | * Comparable class that holds a task and the hint/text for a event
25 | **/
26 | public class TaskAndHint extends Base implements Comparable {
27 |
28 | private String text;
29 | private Task task;
30 |
31 | public TaskAndHint() {
32 | // do nothing
33 | }
34 |
35 | public TaskAndHint(String text, Task task) {
36 | this.text = text;
37 | this.task = task;
38 | }
39 |
40 | public String getText() {
41 | return this.text;
42 | }
43 |
44 | public void setText(String text) {
45 | this.text = text;
46 | }
47 |
48 | public Task getTask() {
49 | return this.task;
50 | }
51 |
52 | public void setTask(Task task) {
53 | this.task = task;
54 | }
55 |
56 | @Override
57 | public int compareTo(TaskAndHint another) {
58 | return compare(getTask(), another.getTask(), compare(getText(), another.getText(), 0));
59 | }
60 |
61 | @Override
62 | public String toString() {
63 | return task.toString() + " " + (this.text == null ? "" : "'" + this.text + "'");
64 | }
65 |
66 | @Override
67 | public int hashCode() {
68 | return Objects.hash(task, text);
69 | }
70 |
71 | @Override
72 | public boolean equals(Object obj) {
73 | if (this == obj)
74 | return true;
75 | if (obj == null)
76 | return false;
77 | if (getClass() != obj.getClass())
78 | return false;
79 |
80 | TaskAndHint other = (TaskAndHint) obj;
81 | if (task == null) {
82 | if (other.getTask() == null) {
83 | if (text == null) {
84 | return other.getText() == null;
85 | }
86 | return text.equals(other.getText());
87 | }
88 | return false;
89 | } else if (text == null) {
90 | if (other.getText() == null) {
91 | return task.equals(other.getTask());
92 | }
93 | return false;
94 | } else {
95 | return task.equals(other.getTask()) && text.equals(other.getText());
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_main_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
78 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/report/TimeSumsHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.report;
17 |
18 | import androidx.annotation.NonNull;
19 |
20 | import org.apache.commons.lang3.builder.CompareToBuilder;
21 | import org.zephyrsoft.trackworktime.model.TimeSum;
22 |
23 | /**
24 | * Holds the data for reporting.
25 | */
26 | public class TimeSumsHolder implements Comparable {
27 |
28 | private String month;
29 | private String week;
30 | private String day;
31 | private String task;
32 | private TimeSum spent;
33 |
34 | public TimeSumsHolder(String month, String week, String day, String task, TimeSum spent) {
35 | this.month = month;
36 | this.week = week;
37 | this.day = day;
38 | this.task = task;
39 | this.spent = spent;
40 | }
41 |
42 | public static @NonNull TimeSumsHolder createForDay(String day, String task, TimeSum spent) {
43 | return new TimeSumsHolder(null, null, day, task, spent);
44 | }
45 |
46 | public static @NonNull TimeSumsHolder createForWeek(String week, String task, TimeSum spent) {
47 | return new TimeSumsHolder(null, week, null, task, spent);
48 | }
49 |
50 | public static @NonNull TimeSumsHolder createForMonth(String month, String task, TimeSum spent) {
51 | return new TimeSumsHolder(month, null, null, task, spent);
52 | }
53 |
54 | public String getDay() {
55 | return day;
56 | }
57 |
58 | public void setDay(String day) {
59 | this.day = day;
60 | }
61 |
62 | public String getWeek() {
63 | return week;
64 | }
65 |
66 | public void setWeek(String week) {
67 | this.week = week;
68 | }
69 |
70 | public String getMonth() {
71 | return month;
72 | }
73 |
74 | public void setMonth(String month) {
75 | this.month = month;
76 | }
77 |
78 | public String getTask() {
79 | return task;
80 | }
81 |
82 | public void setTask(String task) {
83 | this.task = task;
84 | }
85 |
86 | public TimeSum getSpent() {
87 | return spent;
88 | }
89 |
90 | public void setSpent(TimeSum spent) {
91 | this.spent = spent;
92 | }
93 |
94 | @Override
95 | public int compareTo(TimeSumsHolder another) {
96 | if (another == null) {
97 | return 1;
98 | }
99 | return new CompareToBuilder()
100 | .append(getMonth(), another.getMonth())
101 | .append(getWeek(), another.getWeek())
102 | .append(getDay(), another.getDay())
103 | .append(getTask(), another.getTask())
104 | .toComparison();
105 | }
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/report/TargetDaysHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.report;
17 |
18 | import androidx.annotation.NonNull;
19 |
20 | import org.apache.commons.lang3.builder.CompareToBuilder;
21 |
22 | /**
23 | * Holds the data for reporting.
24 | */
25 | public class TargetDaysHolder implements Comparable {
26 |
27 | private String month;
28 | private String week;
29 | private String day;
30 | private String target;
31 | private Integer days;
32 |
33 | public TargetDaysHolder(String month, String week, String day, String target, Integer days) {
34 | this.month = month;
35 | this.week = week;
36 | this.day = day;
37 | this.target = target;
38 | this.days = days;
39 | }
40 |
41 | public static @NonNull
42 | TargetDaysHolder createForDay(String day, String target, Integer days) {
43 | return new TargetDaysHolder(null, null, day, target, days);
44 | }
45 |
46 | public static @NonNull
47 | TargetDaysHolder createForWeek(String week, String target, Integer days) {
48 | return new TargetDaysHolder(null, week, null, target, days);
49 | }
50 |
51 | public static @NonNull
52 | TargetDaysHolder createForMonth(String month, String target, Integer days) {
53 | return new TargetDaysHolder(month, null, null, target, days);
54 | }
55 |
56 | public String getDay() {
57 | return day;
58 | }
59 |
60 | public void setDay(String day) {
61 | this.day = day;
62 | }
63 |
64 | public String getWeek() {
65 | return week;
66 | }
67 |
68 | public void setWeek(String week) {
69 | this.week = week;
70 | }
71 |
72 | public String getMonth() {
73 | return month;
74 | }
75 |
76 | public void setMonth(String month) {
77 | this.month = month;
78 | }
79 |
80 | public String getTarget() {
81 | return target;
82 | }
83 |
84 | public void setTarget(String target) {
85 | this.target = target;
86 | }
87 |
88 | public Integer getDays() {
89 | return days;
90 | }
91 |
92 | public void setDays(Integer days) {
93 | this.days = days;
94 | }
95 |
96 | @Override
97 | public int compareTo(TargetDaysHolder another) {
98 | if (another == null) {
99 | return 1;
100 | }
101 | return new CompareToBuilder()
102 | .append(getMonth(), another.getMonth())
103 | .append(getWeek(), another.getWeek())
104 | .append(getDay(), another.getDay())
105 | .append(getTarget(), another.getTarget())
106 | .toComparison();
107 | }
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/app/src/test/java/org/zephyrsoft/trackworktime/model/TimeSumTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.model;
17 |
18 | import org.junit.BeforeClass;
19 | import org.junit.Test;
20 |
21 | import static org.junit.Assert.assertEquals;
22 |
23 | public class TimeSumTest {
24 |
25 | private TimeSum underTest = new TimeSum();
26 |
27 | @BeforeClass
28 | public static void defaultState() {
29 | TimeSum timeSum = new TimeSum();
30 | assertEquals("Initial time sum", "0:00", timeSum.toString());
31 | }
32 |
33 | @BeforeClass
34 | public static void set() {
35 | TimeSum timeSum = new TimeSum();
36 |
37 | timeSum.set(0, 45);
38 | assertEquals("0:45", timeSum.toString());
39 |
40 | timeSum.set(-1, 45);
41 | assertEquals("-1:45", timeSum.toString());
42 | }
43 |
44 | @Test
45 | public void add() {
46 | add(0, 75);
47 | assertTime("1:15");
48 |
49 | add(2, 65);
50 | assertTime("4:20");
51 | }
52 |
53 | private void add(int h, int min) {
54 | underTest.add(h, min);
55 | }
56 |
57 | @Test
58 | public void substract() {
59 | set(4, 20);
60 |
61 | subtract(0, 140);
62 | assertTime("2:00");
63 |
64 | subtract(1, 75);
65 | assertTime("-0:15");
66 |
67 | subtract(1, 50);
68 | assertTime("-2:05");
69 | }
70 |
71 | private void subtract(int h, int min) {
72 | underTest.substract(h, min);
73 | }
74 |
75 | @Test
76 | public void addOrSustract() {
77 | set(-2, 5);
78 |
79 | TimeSum positive = new TimeSum();
80 | positive.set(2, 30);
81 | addOrSubtract(positive);
82 | assertTime("0:25");
83 |
84 | TimeSum negative = new TimeSum();
85 | negative.set(-1, 25);
86 | addOrSubtract(negative);
87 | assertTime("-1:00");
88 | }
89 |
90 | private void addOrSubtract(TimeSum other) {
91 | underTest.addOrSubstract(other);
92 | }
93 |
94 | @Test
95 | public void reset() {
96 | set(-1, 0);
97 |
98 | underTest.reset();
99 | assertTime("0:00");
100 | }
101 |
102 | private void assertTime(String expectedTime) {
103 | assertEquals(expectedTime, underTest.toString());
104 | }
105 |
106 | @Test
107 | public void getAsMinutes() {
108 | assertEquals(0, getAsMin());
109 |
110 | set(1, 30);
111 | assertEquals(90, getAsMin());
112 |
113 | set(-1, 30);
114 | assertEquals(-90, getAsMin());
115 | }
116 |
117 | private int getAsMin() {
118 | return underTest.getAsMinutes();
119 | }
120 |
121 | private void set(int h, int min) {
122 | underTest.set(h, min);
123 | }
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/app/src/main/java/org/zephyrsoft/trackworktime/options/DurationPreferenceDialogFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of TrackWorkTime (TWT).
3 | *
4 | * TWT is free software: you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License 3.0 as published by
6 | * the Free Software Foundation.
7 | *
8 | * TWT is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License 3.0 for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License 3.0
14 | * along with TWT. If not, see .
15 | */
16 | package org.zephyrsoft.trackworktime.options;
17 |
18 | import android.content.Context;
19 | import android.content.DialogInterface;
20 | import android.text.Editable;
21 | import android.text.TextWatcher;
22 | import android.view.View;
23 | import android.widget.Button;
24 | import android.widget.EditText;
25 |
26 | import androidx.annotation.NonNull;
27 | import androidx.appcompat.app.AlertDialog;
28 | import androidx.preference.PreferenceDialogFragmentCompat;
29 |
30 | import org.zephyrsoft.trackworktime.R;
31 | import org.zephyrsoft.trackworktime.util.DateTimeUtil;
32 |
33 | public class DurationPreferenceDialogFragment extends PreferenceDialogFragmentCompat {
34 |
35 | private EditText editText;
36 |
37 | @Override
38 | protected void onPrepareDialogBuilder(@NonNull AlertDialog.Builder builder) {
39 | super.onPrepareDialogBuilder(builder);
40 | builder.setMessage(getPreference().getSummary() + "\n");
41 | }
42 |
43 | @Override
44 | protected View onCreateDialogView(Context context) {
45 | editText = new EditText(context);
46 | return editText;
47 | }
48 |
49 | @Override
50 | protected void onBindDialogView(View view) {
51 | super.onBindDialogView(view);
52 |
53 | DurationPreference pref = (DurationPreference) getPreference();
54 | editText.setText(pref.getDuration());
55 | }
56 |
57 | @Override
58 | public void onStart() {
59 | super.onStart();
60 |
61 | final Button buttonPositive = ((AlertDialog) getDialog()).getButton(DialogInterface.BUTTON_POSITIVE);
62 | editText.addTextChangedListener(new TextWatcher() {
63 | @Override
64 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
65 | // not used
66 | }
67 |
68 | @Override
69 | public void onTextChanged(CharSequence s, int start, int before, int count) {
70 | // not used
71 | }
72 |
73 | @Override public void afterTextChanged(Editable s) {
74 | if (DateTimeUtil.isDurationValid(editText.getText().toString())) {
75 | editText.setError(null);
76 | buttonPositive.setEnabled(true);
77 | } else {
78 | editText.setError(getString(R.string.invalidDuration));
79 | buttonPositive.setEnabled(false);
80 | }
81 | }
82 | });
83 | }
84 |
85 | @Override
86 | public void onDialogClosed(boolean positiveResult) {
87 |
88 | if (positiveResult) {
89 | DurationPreference pref = (DurationPreference) getPreference();
90 |
91 | pref.updateValue(editText.getText().toString());
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------