diff --git a/app/build.gradle b/app/build.gradle index 462ef66..2a2ead1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -21,7 +21,7 @@ android { applicationId "in.sminnovations.hpostesting.server" minSdk 30 targetSdk 34 - versionCode 138 + versionCode 139 versionName "2.1.133" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { diff --git a/app/src/main/java/com/example/hpostesting/presentation/main_base/SettingsFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/main_base/SettingsFragment.kt index 26b18a9..28a23f0 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/main_base/SettingsFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/main_base/SettingsFragment.kt @@ -17,6 +17,9 @@ import android.content.Context import android.content.SharedPreferences import android.content.pm.PackageManager import android.os.Bundle +import android.text.InputFilter +import android.text.InputType +import android.view.Gravity import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -26,6 +29,7 @@ import android.widget.Toast import androidx.core.content.ContextCompat import androidx.core.content.edit import androidx.fragment.app.Fragment +import androidx.preference.EditTextPreference import androidx.preference.ListPreference import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat @@ -42,7 +46,12 @@ import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding private var isLanguageChanged = false - +private val DEFAULT_DISCLAIMER = """ +DISCLAIMER: This report is generated by HemoCube automated system. +Results should be interpreted by qualified medical professionals. +This report is for diagnostic purposes only and should not be used as the sole basis for medical decisions. +Please consult with your healthcare provider for proper interpretation and treatment recommendations. +""".trimIndent() class SlideshowFragment : Fragment() { private var selectedItem = "10mm" private val values = arrayOf("10mm", "2mm") @@ -121,6 +130,7 @@ class PrefsFragment : PreferenceFragmentCompat() { private lateinit var currentServerPreference: Preference lateinit var firebaseManager: FirebaseManager var autoSmbtValue = false + var reportDisclaimerText = DEFAULT_DISCLAIMER private var topDevMode = false lateinit var databaseRepository: DatabaseRepository @@ -132,10 +142,11 @@ class PrefsFragment : PreferenceFragmentCompat() { val sharedPreference = requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) autoSmbtValue = sharedPreference.getBoolean("AutSmbt", false) + reportDisclaimerText = sharedPreference.getString("report_dis_txt", DEFAULT_DISCLAIMER).toString() val preferenceScreen = preferenceManager.createPreferenceScreen(requireContext()) val currentServer = firebaseManager.getLastSelectedServer().serverName val arWeAdmin =sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN" - + val MAX_CHARS = 10_000 // Language Preference val languagePreference = ListPreference(requireContext()).apply { key = "language_preference" @@ -202,6 +213,52 @@ class PrefsFragment : PreferenceFragmentCompat() { } } + val disclaimerPreference = EditTextPreference(requireContext()).apply { + key = "Report_disclaimer" + title = "Report disclaimer Editor" + icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_add) + summaryProvider = Preference.SummaryProvider { preference -> + val value = preference.text + if (value.isNullOrBlank()) { + "Current disclaimer: (not set)" + } else { + "Current disclaimer: $value" + } + } + setOnBindEditTextListener { edit -> + edit.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE + edit.minLines = 4 + edit.maxLines = 10 + edit.gravity = Gravity.TOP or Gravity.START + edit.filters = arrayOf(InputFilter.LengthFilter(MAX_CHARS)) + } + setOnPreferenceChangeListener { _, newValue -> + val text = (newValue as? String)?.trim().orEmpty() + if (text.length > MAX_CHARS) { + Toast.makeText( + requireContext(), + "Text too long (${text.length}/$MAX_CHARS).", + Toast.LENGTH_SHORT + ).show() + return@setOnPreferenceChangeListener false + }else{ + sharedPreference.edit().putString("report_dis_txt", text).apply() + } + true + } + } + val resetDisclaimerPreference = Preference(requireContext()).apply { + title = "Reset to default Disclaimer" + summary = "Replace the current text with the app’s default disclaimer" + icon = ContextCompat.getDrawable(requireContext(), R.drawable.baseline_restore_24) + setOnPreferenceClickListener { + sharedPreference.edit().putString("report_dis_txt", DEFAULT_DISCLAIMER).apply() + disclaimerPreference.text = DEFAULT_DISCLAIMER + Toast.makeText(requireContext(), "Disclaimer reset to default", Toast.LENGTH_SHORT).show() + true + } + } + val autosmbt = SwitchPreferenceCompat(requireContext()).apply { title = "Auto submit" summary = "Enable or disable Auto submit" @@ -238,7 +295,9 @@ class PrefsFragment : PreferenceFragmentCompat() { if (preferenceScreen.findPreference("developer_options") == null) { preferenceScreen.addPreference(developerToggle) - preferenceScreen.addPreference(autosmbt) + preferenceScreen.addPreference(autosmbt) + preferenceScreen.addPreference(disclaimerPreference) + preferenceScreen.addPreference(resetDisclaimerPreference) } if (preferenceScreen.findPreference("server_preference") == null) { @@ -258,8 +317,11 @@ class PrefsFragment : PreferenceFragmentCompat() { if (firebaseManager.getDevMode() && arWeAdmin) { developerToggle.isChecked = true // Ensure it's checked preferenceScreen.addPreference(developerToggle) - preferenceScreen.addPreference(autosmbt) preferenceScreen.addPreference(serverSelectorPreference) + preferenceScreen.addPreference(autosmbt) + preferenceScreen.addPreference(resetDisclaimerPreference) + preferenceScreen.addPreference(disclaimerPreference) + } setPreferenceScreen(preferenceScreen) @@ -269,6 +331,12 @@ class PrefsFragment : PreferenceFragmentCompat() { } } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + listView.setPadding(0, 0, 0, 300) // Add bottom padding + listView.clipToPadding = false + } + private fun updateServerPreference(newServer: String) { (findPreference("server_preference"))?.let { pref -> diff --git a/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/PrintObject.kt b/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/PrintObject.kt index d8a8aed..33adfdb 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/PrintObject.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/PrintObject.kt @@ -30,7 +30,7 @@ object ReportGen { private const val MARGIN_TOP = 80f private const val MARGIN_BOTTOM = 80f - fun generate(context: Context, dataList: List) { + fun generate(context: Context, dataList: List,disclaimerText: String) { if (dataList.isEmpty()) { Toast.makeText(context, "No items selected for report generation", Toast.LENGTH_SHORT).show() return @@ -45,11 +45,11 @@ object ReportGen { } Toast.makeText(context, message, Toast.LENGTH_SHORT).show() - val pdfFile = createProfessionalPdfReport(context, dataList) + val pdfFile = createProfessionalPdfReport(context, dataList, disclaimerText) previewPdf(context, pdfFile) } - private fun createProfessionalPdfReport(context: Context, dataList: List): File { + private fun createProfessionalPdfReport(context: Context, dataList: List,disclaimerText : String): File { val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date()) val file = File(context.getExternalFilesDir(null), "HemoCube_Report_$timestamp.pdf") @@ -99,7 +99,7 @@ object ReportGen { drawPage(canvas, testData, index + 1, dataList.size, headerPaint, titlePaint, sectionHeaderPaint, - contentPaint, boldContentPaint, disclaimerPaint,context) + contentPaint, boldContentPaint, disclaimerPaint,disclaimerText,context) pdfDocument.finishPage(page) } @@ -120,6 +120,7 @@ object ReportGen { contentPaint: Paint, boldContentPaint: Paint, disclaimerPaint: Paint, + disclaimerText: String, context: Context ) { var currentY = MARGIN_TOP @@ -165,7 +166,7 @@ object ReportGen { currentY += 15f // Footer with page number and disclaimer - drawFooter(canvas, pageNumber, totalPages, contentPaint, disclaimerPaint) + drawFooter(canvas, pageNumber, totalPages, contentPaint, disclaimerPaint,disclaimerText) } private fun drawHeader(canvas: Canvas, headerPaint: Paint, titlePaint: Paint, startY: Float, context: Context) { @@ -256,17 +257,13 @@ object ReportGen { return currentY } - private fun drawFooter(canvas: Canvas, pageNumber: Int, totalPages: Int, contentPaint: Paint, disclaimerPaint: Paint) { + private fun drawFooter(canvas: Canvas, pageNumber: Int, totalPages: Int, contentPaint: Paint, disclaimerPaint: Paint,disclaimerText: String) { val footerY = PAGE_HEIGHT - MARGIN_BOTTOM + 20f // Page number canvas.drawText("Page $pageNumber of $totalPages", PAGE_WIDTH - MARGIN_RIGHT - 80f, footerY, contentPaint) // Disclaimer - val disclaimerText = "DISCLAIMER: This report is generated by HemoCube automated system. " + - "Results should be interpreted by qualified medical professionals. " + - "This report is for diagnostic purposes only and should not be used as the sole basis for medical decisions. " + - "Please consult with your healthcare provider for proper interpretation and treatment recommendations." val disclaimerLines = wrapText(disclaimerText, disclaimerPaint, PAGE_WIDTH - MARGIN_LEFT - MARGIN_RIGHT) var disclaimerY = footerY + 20f diff --git a/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/ReportFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/ReportFragment.kt index 8ba89bd..72cff78 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/ReportFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/reportgen/ui/report/ReportFragment.kt @@ -2,6 +2,7 @@ package com.example.hpostesting.presentation.reportgen.ui.report import android.app.DatePickerDialog import android.content.Context +import android.content.SharedPreferences import android.os.Bundle import android.util.Log import android.view.LayoutInflater @@ -26,12 +27,21 @@ import java.text.SimpleDateFormat import java.util.Calendar import java.util.Date import java.util.Locale + +private val DEFAULT_DISCLAIMER = """ +DISCLAIMER: This report is generated by HemoCube automated system. +Results should be interpreted by qualified medical professionals. +This report is for diagnostic purposes only and should not be used as the sole basis for medical decisions. +Please consult with your healthcare provider for proper interpretation and treatment recommendations. +""".trimIndent() + @AndroidEntryPoint class ReportFragment : Fragment() { companion object { fun newInstance() = ReportFragment() } + private lateinit var sharedPreferences: SharedPreferences private val viewModel: ReportViewModel by viewModels() @@ -47,12 +57,14 @@ class ReportFragment : Fragment() { private var allData: List = emptyList() private var currentFilter = "Today" private var customDate: String? = null - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? + ): View = inflater.inflate(R.layout.fragment_report, container, false) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + sharedPreferences = requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) initViews(view) setupRecyclerView() setupFilterSpinner() @@ -133,7 +145,8 @@ class ReportFragment : Fragment() { generateBtn.setOnClickListener { if (selectedItems.isNotEmpty()) { - ReportGen.generate(requireContext(), selectedItems) + ReportGen.generate(requireContext(), selectedItems, disclaimerText = sharedPreferences.getString("report_dis_txt", + DEFAULT_DISCLAIMER).toString()) } } } diff --git a/app/src/main/res/drawable/baseline_restore_24.xml b/app/src/main/res/drawable/baseline_restore_24.xml new file mode 100644 index 0000000..6ad75a1 --- /dev/null +++ b/app/src/main/res/drawable/baseline_restore_24.xml @@ -0,0 +1,5 @@ + + + + +