app/src/main/java/com/futsch1/medtimer/OptionsMenu.java
package com.futsch1.medtimer;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import androidx.appcompat.view.menu.MenuBuilder;
import androidx.core.view.MenuProvider;
import androidx.navigation.NavController;
import com.futsch1.medtimer.exporters.CSVExport;
import com.futsch1.medtimer.exporters.Exporter;
import com.futsch1.medtimer.exporters.PDFExport;
import com.futsch1.medtimer.helpers.FileHelper;
import com.futsch1.medtimer.helpers.PathHelper;
import com.futsch1.medtimer.reminders.ReminderProcessor;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.TimeZone;
public class OptionsMenu implements MenuProvider {
private final Context context;
private final MedicineViewModel medicineViewModel;
private final ActivityResultLauncher<Intent> openFileLauncher;
private final NavController navController;
private final HandlerThread backgroundThread;
private Menu menu;
private BackupManager backupManager;
public OptionsMenu(Context context, MedicineViewModel medicineViewModel, ActivityResultLauncher<Intent> openFileLauncher, NavController navController) {
this.context = context;
this.medicineViewModel = medicineViewModel;
this.openFileLauncher = openFileLauncher;
this.navController = navController;
backgroundThread = new HandlerThread("Export");
backgroundThread.start();
}
@Override
public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menuInflater.inflate(R.menu.main, menu);
menu.setGroupDividerEnabled(true);
enableOptionalIcons(menu);
this.backupManager = new BackupManager(context, menu, medicineViewModel, openFileLauncher);
this.menu = menu;
setupSettings();
setupVersion();
setupAppURL();
setupClearEvents();
setupExport();
setupGenerateTestData();
setupShowAppIntro();
}
@SuppressLint("RestrictedApi")
private static void enableOptionalIcons(@NonNull Menu menu) {
if (menu instanceof MenuBuilder) {
try {
Method m = menu.getClass().getDeclaredMethod(
"setOptionalIconsVisible", Boolean.TYPE);
m.invoke(menu, true);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
Log.e("Menu", "onMenuOpened", e);
}
}
}
private void setupSettings() {
MenuItem item = menu.findItem(R.id.settings);
item.setOnMenuItemClickListener(menuItem -> {
navController.navigate(R.id.action_global_preferencesFragment);
return true;
});
}
private void setupVersion() {
MenuItem item = menu.findItem(R.id.version);
item.setTitle(context.getString(R.string.version, BuildConfig.VERSION_NAME));
}
private void setupAppURL() {
MenuItem item = menu.findItem(R.id.app_url);
item.setOnMenuItemClickListener(menuItem -> {
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/Futsch1/medTimer"));
context.startActivity(myIntent);
return true;
});
}
private void setupClearEvents() {
MenuItem item = menu.findItem(R.id.clear_events);
item.setOnMenuItemClickListener(menuItem -> {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.confirm);
builder.setMessage(R.string.are_you_sure_delete_events);
builder.setCancelable(false);
builder.setPositiveButton(R.string.yes, (dialogInterface, i) -> medicineViewModel.deleteReminderEvents());
builder.setNegativeButton(R.string.cancel, (dialogInterface, i) -> { // Intentionally left empty
});
builder.show();
ReminderProcessor.requestReschedule(context);
return true;
});
}
private void setupExport() {
Handler handler = new Handler(backgroundThread.getLooper());
MenuItem item = menu.findItem(R.id.export_csv);
item.setOnMenuItemClickListener(menuItem -> {
handler.post(() -> export(new CSVExport(medicineViewModel.medicineRepository.getAllReminderEventsWithoutDeleted(), context, TimeZone.getDefault().toZoneId())));
return true;
});
item = menu.findItem(R.id.export_pdf);
item.setOnMenuItemClickListener(menuItem -> {
handler.post(() -> export(new PDFExport(medicineViewModel.medicineRepository.getAllReminderEventsWithoutDeleted(), context, TimeZone.getDefault().toZoneId())));
return true;
});
}
void setupGenerateTestData() {
MenuItem item = menu.findItem(R.id.generate_test_data);
if (BuildConfig.DEBUG) {
item.setVisible(true);
item.setOnMenuItemClickListener(menuItem -> {
final Handler handler = new Handler(backgroundThread.getLooper());
handler.post(() -> {
Log.i("GenerateTestData", "Delete all data");
medicineViewModel.deleteAll();
GenerateTestData generateTestData = new GenerateTestData(medicineViewModel);
Log.i("GenerateTestData", "Generate new medicine");
generateTestData.generateTestMedicine();
});
handler.post(() -> ReminderProcessor.requestReschedule(context));
return true;
});
} else {
item.setVisible(false);
}
}
private void setupShowAppIntro() {
if (BuildConfig.DEBUG) {
MenuItem item = menu.findItem(R.id.show_app_intro);
item.setOnMenuItemClickListener(menuItem -> {
context.startActivity(new Intent(context, MedTimerAppIntro.class));
return true;
});
}
}
private void export(Exporter exporter) {
File csvFile = new File(context.getCacheDir(), PathHelper.getExportFilename(exporter));
try {
exporter.export(csvFile);
FileHelper.shareFile(context, csvFile);
} catch (Exporter.ExporterException e) {
Toast.makeText(context, R.string.export_failed, Toast.LENGTH_LONG).show();
}
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
return false;
}
public void fileSelected(Uri data) {
backupManager.fileSelected(data);
}
}