Compare commits

...

10 commits

Author SHA1 Message Date
29a4a1dae3 Version 1.3.0. 2023-12-26 19:14:16 -08:00
31c77528d7 Fix behavior of track delete button after using when was I here.
The delete button was deleting all points between the first and last,
which, when you use the "when was I here" button, could span days
or months that you don't want to delete. So, after doing a spatial
query, the delete button will only delete the points that are shown.
2023-12-25 21:37:35 -08:00
535133ce22 Rename deleteButton to delete_whole_track_button. 2023-12-25 20:13:59 -08:00
a04a0d3a3a Show current position on Track view.
This primarily helps when you want to use the "when was I here" button,
to remember a previous day when you were at the same location.

Besides that, seeing the current realtime location provides helpful
context to historical tracks.
2023-12-24 22:23:27 -08:00
eb1ad45c4c Remove permission launcher from MapFragment, already in MainActivity. 2023-12-24 22:20:43 -08:00
47c338f38f Rename tracker_service variables for clarity. 2023-12-24 22:19:35 -08:00
cd25415e9b Remove unneeded thismapfragment. 2023-12-24 22:18:34 -08:00
a75ee66ca4 Remove code for toggleLocationErrorBar. 2023-12-24 22:18:10 -08:00
70e6e64918 Let "when was I here" button query all device ids. 2023-12-24 19:47:13 -08:00
d5df922d3d Version 1.2.1. 2023-12-24 19:28:33 -08:00
7 changed files with 190 additions and 98 deletions

View file

@ -10,8 +10,8 @@ android {
applicationId 'net.voussoir.trkpt'
minSdkVersion 25
targetSdk 32
versionCode 56
versionName '1.2.0'
versionCode 58
versionName '1.3.0'
resConfigs "en", "da", "de", "fr", "hr", "id", "it", "ja", "nb-rNO", "nl", "pl", "pt-rBR", "ru", "sv", "tr", "zh-rCN"
}

View file

@ -56,11 +56,11 @@ class Database(val trackbook: Trackbook)
this.connection.endTransaction()
}
fun delete_trkpt(device_id: String, time: Long)
fun delete_trkpt(trkpt: Trkpt)
{
Log.i("VOUSSOIR", "Database.delete_trkpt")
begin_transaction()
connection.delete("trkpt", "device_id = ? AND time = ?", arrayOf(device_id, time.toString()))
connection.delete("trkpt", "device_id = ? AND time = ?", arrayOf(trkpt.device_id, trkpt.time.toString()))
}
fun delete_trkpt_start_end(device_id: String, start_time: Long, end_time: Long)
@ -101,18 +101,33 @@ class Database(val trackbook: Trackbook)
))
}
fun select_trkpt_bounding_box(device_id: String, north: Double, south: Double, east: Double, west: Double, max_accuracy: Float=Keys.DEFAULT_MAX_ACCURACY): Iterator<Trkpt>
fun select_trkpt_bounding_box(device_id: String?, north: Double, south: Double, east: Double, west: Double, max_accuracy: Float=Keys.DEFAULT_MAX_ACCURACY): Iterator<Trkpt>
{
Log.i("VOUSSOIR", "Track.trkpt_generator: Querying points between $north, $south, $east, $west.")
return _trkpt_generator(this.connection.rawQuery(
"""
if (device_id == null)
{
return _trkpt_generator(this.connection.rawQuery(
"""
SELECT device_id, lat, lon, time, provider, ele, accuracy, sat
FROM trkpt
WHERE lat >= ? AND lat <= ? AND lon >= ? AND lon <= ? AND accuracy <= ?
ORDER BY time ASC
""",
arrayOf(south.toString(), north.toString(), west.toString(), east.toString(), max_accuracy.toString())
))
}
else
{
return _trkpt_generator(this.connection.rawQuery(
"""
SELECT device_id, lat, lon, time, provider, ele, accuracy, sat
FROM trkpt
WHERE device_id = ? AND lat >= ? AND lat <= ? AND lon >= ? AND lon <= ? AND accuracy <= ?
ORDER BY time ASC
""",
arrayOf(device_id, south.toString(), north.toString(), west.toString(), east.toString(), max_accuracy.toString())
))
arrayOf(device_id, south.toString(), north.toString(), west.toString(), east.toString(), max_accuracy.toString())
))
}
}
fun _trkpt_generator(cursor: Cursor) = iterator<Trkpt>

View file

@ -79,6 +79,10 @@ object Keys {
const val STATE_THEME_LIGHT_MODE: String = "stateLightMode"
const val STATE_THEME_DARK_MODE: String = "stateDarkMode"
// Track view
const val SELECTION_MODE_STARTSTOP = 1
const val SELECTION_MODE_SPATIAL = 2
// dialog types
const val DIALOG_DELETE_TRACK: Int = 1

View file

@ -47,6 +47,7 @@ class MainActivity: AppCompatActivity()
/* Overrides onCreate from AppCompatActivity */
override fun onCreate(savedInstanceState: Bundle?)
{
Log.i("VOUSSOIR", "MainActivity.onCreate")
trackbook = (applicationContext as Trackbook)
super.onCreate(savedInstanceState)
request_permissions(this)
@ -125,6 +126,7 @@ class MainActivity: AppCompatActivity()
/* Overrides onDestroy from AppCompatActivity */
override fun onDestroy()
{
Log.i("VOUSSOIR", "MainActivity.onDestroy")
super.onDestroy()
// unregister listener for changes in shared preferences
PreferencesHelper.unregisterPreferenceChangeListener(sharedPreferenceChangeListener)

View file

@ -39,7 +39,6 @@ import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.Snackbar
import org.osmdroid.events.MapEventsReceiver
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
import org.osmdroid.util.GeoPoint
@ -57,15 +56,16 @@ class MapFragment : Fragment()
{
private lateinit var trackbook: Trackbook
private var bound: Boolean = false
private var tracker_service_bound: Boolean = false
private var tracker_service: TrackerService? = null
val handler: Handler = Handler(Looper.getMainLooper())
var continuous_auto_center: Boolean = true
private var trackerService: TrackerService? = null
private lateinit var database_changed_listener: DatabaseChangedListener
var show_debug: Boolean = false
var thismapfragment: MapFragment? = null
private lateinit var database_changed_listener: DatabaseChangedListener
lateinit var rootView: View
private lateinit var mapView: MapView
lateinit var mainButton: ExtendedFloatingActionButton
@ -77,14 +77,12 @@ class MapFragment : Fragment()
private var current_track_overlay: Polyline? = null
private var current_position_overlays = ArrayList<Overlay>()
private var homepoints_overlays = ArrayList<Overlay>()
private lateinit var locationErrorBar: Snackbar
/* Overrides onCreate from Fragment */
override fun onCreate(savedInstanceState: Bundle?)
{
Log.i("VOUSSOIR", "MapFragment.onCreate")
super.onCreate(savedInstanceState)
thismapfragment = this
this.trackbook = (requireContext().applicationContext as Trackbook)
database_changed_listener = object: DatabaseChangedListener
{
@ -116,7 +114,6 @@ class MapFragment : Fragment()
zoom_out_button = rootView.findViewById(R.id.zoom_out_button)
map_current_time = rootView.findViewById(R.id.map_current_time)
mainButton = rootView.findViewById(R.id.main_button)
locationErrorBar = Snackbar.make(mapView, String(), Snackbar.LENGTH_INDEFINITE)
mapView.setOnLongClickListener{
Log.i("VOUSSOIR", "mapview longpress")
@ -198,7 +195,7 @@ class MapFragment : Fragment()
}
mainButton.setOnClickListener {
val tracker = trackerService
val tracker = tracker_service
if (tracker == null)
{
return@setOnClickListener
@ -214,7 +211,7 @@ class MapFragment : Fragment()
handler.postDelayed(redraw_runnable, 0)
}
currentLocationButton.setOnClickListener {
val tracker = trackerService
val tracker = tracker_service
if (tracker == null)
{
return@setOnClickListener
@ -240,13 +237,7 @@ class MapFragment : Fragment()
{
Log.i("VOUSSOIR", "MapFragment.onStart")
super.onStart()
// request location permission if denied
if (ContextCompat.checkSelfPermission(activity as Context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED)
{
requestLocationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
}
// bind to TrackerService
activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE)
activity?.bindService(Intent(activity, TrackerService::class.java), tracker_service_connection, Context.BIND_AUTO_CREATE)
handler.post(redraw_runnable)
}
@ -270,13 +261,13 @@ class MapFragment : Fragment()
super.onPause()
requireActivity().window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
val tracker = trackerService
val tracker = tracker_service
if (tracker == null)
{
return
}
saveBestLocationState(tracker.currentBestLocation)
if (bound && (tracker.tracking_state == Keys.STATE_MAPVIEW || tracker.tracking_state == Keys.STATE_STOP))
if (tracker_service_bound && (tracker.tracking_state == Keys.STATE_MAPVIEW || tracker.tracking_state == Keys.STATE_STOP))
{
tracker.remove_gps_location_listener()
tracker.remove_network_location_listener()
@ -290,9 +281,9 @@ class MapFragment : Fragment()
{
super.onStop()
// unbind from TrackerService
if (bound)
if (tracker_service_bound)
{
activity?.unbindService(connection)
activity?.unbindService(tracker_service_connection)
handleServiceUnbind()
}
handler.removeCallbacks(redraw_runnable)
@ -317,24 +308,6 @@ class MapFragment : Fragment()
handler.removeCallbacks(redraw_runnable)
}
private val requestLocationPermissionLauncher = registerForActivityResult(RequestPermission()) { isGranted: Boolean ->
if (isGranted)
{
// permission was granted - re-bind service
activity?.unbindService(connection)
activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE)
Log.i("VOUSSOIR", "Request result: Location permission has been granted.")
}
else
{
// permission denied - unbind service
activity?.unbindService(connection)
}
val gpsProviderActive = if (trackerService == null) false else trackerService!!.gpsProviderActive
val networkProviderActive = if (trackerService == null) false else trackerService!!.networkProviderActive
toggleLocationErrorBar(gpsProviderActive, networkProviderActive)
}
private fun startTracking()
{
// start service via intent so that it keeps running after unbind
@ -348,9 +321,9 @@ class MapFragment : Fragment()
{
activity?.startService(intent)
}
if (trackerService != null)
if (tracker_service != null)
{
trackerService!!.state_full_recording()
tracker_service!!.state_full_recording()
}
}
@ -358,7 +331,7 @@ class MapFragment : Fragment()
/* Handles state when service is being unbound */
private fun handleServiceUnbind()
{
bound = false
tracker_service_bound = false
// unregister listener for changes in shared preferences
PreferencesHelper.unregisterPreferenceChangeListener(sharedPreferenceChangeListener)
}
@ -397,12 +370,11 @@ class MapFragment : Fragment()
current_position_overlays.clear()
}
/* Mark current position on map */
fun create_current_position_overlays()
{
clear_current_position_overlays()
val tracker = trackerService
val tracker = tracker_service
if (tracker == null)
{
return
@ -579,7 +551,7 @@ class MapFragment : Fragment()
fun update_main_button()
{
val tracker = trackerService
val tracker = tracker_service
mainButton.isEnabled = trackbook.database.ready
currentLocationButton.isVisible = true
if (! trackbook.database.ready)
@ -601,27 +573,7 @@ class MapFragment : Fragment()
}
}
fun toggleLocationErrorBar(gpsProviderActive: Boolean, networkProviderActive: Boolean)
{
if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED)
{
// CASE: Location permission not granted
locationErrorBar.setText(R.string.snackbar_message_location_permission_denied)
if (!locationErrorBar.isShown) locationErrorBar.show()
}
else if (!gpsProviderActive && !networkProviderActive)
{
// CASE: Location setting is off
locationErrorBar.setText(R.string.snackbar_message_location_offline)
if (!locationErrorBar.isShown) locationErrorBar.show()
}
else
{
if (locationErrorBar.isShown) locationErrorBar.dismiss()
}
}
private val connection = object : ServiceConnection {
private val tracker_service_connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder)
{
// get reference to tracker service]
@ -630,8 +582,8 @@ class MapFragment : Fragment()
{
return
}
bound = true
trackerService = serviceref
tracker_service_bound = true
tracker_service = serviceref
// get state of tracking and update button if necessary
redraw()
// register listener for changes in shared preferences
@ -648,7 +600,7 @@ class MapFragment : Fragment()
{
// Log.i("VOUSSOIR", "MapFragment.redraw")
update_main_button()
val tracker = trackerService
val tracker = tracker_service
if (tracker == null)
{
return
@ -693,7 +645,7 @@ class MapFragment : Fragment()
fun state_name(): String
{
val tracker = trackerService
val tracker = tracker_service
if (tracker == null)
{
return "null"

View file

@ -32,7 +32,7 @@ import java.util.*
data class Track (
val database: Database,
val device_id: String,
var device_id: String,
var name: String = "",
var _start_time: Long = 0L,
var _end_time: Long = 0L,

View file

@ -21,12 +21,17 @@
package net.voussoir.trkpt
import YesNoDialog
import android.Manifest
import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.Paint
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.net.Uri
import android.os.Bundle
import android.os.Handler
@ -55,10 +60,7 @@ import org.osmdroid.events.ZoomEvent
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
import org.osmdroid.util.GeoPoint
import org.osmdroid.views.MapView
import org.osmdroid.views.overlay.MapEventsOverlay
import org.osmdroid.views.overlay.Marker
import org.osmdroid.views.overlay.Polyline
import org.osmdroid.views.overlay.TilesOverlay
import org.osmdroid.views.overlay.*
import org.osmdroid.views.overlay.simplefastpoint.SimpleFastPointOverlay
import org.osmdroid.views.overlay.simplefastpoint.SimpleFastPointOverlayOptions
import org.osmdroid.views.overlay.simplefastpoint.SimplePointTheme
@ -71,7 +73,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
lateinit var rootView: View
lateinit var save_track_button: ImageButton
lateinit var deleteButton: ImageButton
lateinit var delete_whole_track_button: ImageButton
lateinit var zoom_in_button: FloatingActionButton
lateinit var zoom_out_button: FloatingActionButton
lateinit var trackNameView: MaterialTextView
@ -93,6 +95,8 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
var ready_to_straighten: Boolean = false
var track_query_start_time_previous: Int = 0
var track_query_end_time_previous: Int = 0
var selection_mode: Int = Keys.SELECTION_MODE_STARTSTOP
private lateinit var mapView: MapView
private lateinit var controller: IMapController
private lateinit var statisticsSheetBehavior: BottomSheetBehavior<View>
@ -115,6 +119,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
private lateinit var track_segment_overlays: ArrayDeque<Polyline>
private var track_geopoints: MutableList<IGeoPoint> = mutableListOf()
private var track_points_overlay: SimpleFastPointOverlay? = null
private var current_position_overlays = ArrayList<Overlay>()
// private lateinit var trkpt_infowindow: InfoWindow
private var useImperialUnits: Boolean = false
private val handler: Handler = Handler(Looper.getMainLooper())
@ -123,6 +128,10 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
var selected_trkpt: Trkpt? = null
lateinit var selected_trkpt_marker: Marker
private lateinit var locationManager: LocationManager
private lateinit var gpsLocationListener: LocationListener
private var gpslistenerregistered = false
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
@ -156,10 +165,12 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
end_time=requested_end_time,
max_accuracy=PreferencesHelper.load_max_accuracy(),
))
selection_mode = Keys.SELECTION_MODE_STARTSTOP
rootView = inflater.inflate(R.layout.fragment_track, container, false)
mapView = rootView.findViewById(R.id.map)
save_track_button = rootView.findViewById(R.id.save_button)
deleteButton = rootView.findViewById(R.id.delete_button)
delete_whole_track_button = rootView.findViewById(R.id.delete_button)
zoom_in_button = rootView.findViewById(R.id.zoom_in_button)
zoom_out_button = rootView.findViewById(R.id.zoom_out_button)
trackNameView = rootView.findViewById(R.id.statistics_track_name_headline)
@ -178,6 +189,20 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
}
controller.setZoom(Keys.DEFAULT_ZOOM_LEVEL)
val has_permission: Boolean = ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
if (has_permission)
{
locationManager = requireContext().getSystemService(Context.LOCATION_SERVICE) as LocationManager
gpsLocationListener = createLocationListener()
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
0,
0f,
gpsLocationListener,
)
gpslistenerregistered = true
}
// trkpt_infowindow = MarkerInfoWindow(R.layout.trkpt_infowindow, mapView)
statisticsSheet = rootView.findViewById(R.id.statistics_sheet)
@ -271,7 +296,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
Log.i("VOUSSOIR", selected.rendered_by_polyline?.actualPoints?.size.toString())
selected.rendered_by_polyline?.setPoints(ArrayList(selected.rendered_by_polyline?.actualPoints))
Log.i("VOUSSOIR", selected.rendered_by_polyline?.actualPoints?.size.toString())
trackbook.database.delete_trkpt(selected.device_id, selected.time)
trackbook.database.delete_trkpt(selected)
trackbook.database.commit()
deselect_trkpt()
mapView.invalidate()
@ -291,6 +316,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
end_time=track.trkpts.last().time,
max_accuracy=PreferencesHelper.load_max_accuracy(),
))
selection_mode = Keys.SELECTION_MODE_STARTSTOP
deselect_trkpt()
render_track()
}
@ -309,6 +335,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
end_time=selected.time,
max_accuracy=PreferencesHelper.load_max_accuracy(),
))
selection_mode = Keys.SELECTION_MODE_STARTSTOP
deselect_trkpt()
render_track()
}
@ -323,12 +350,14 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
val polyline = selected.rendered_by_polyline
if (polyline != null)
{
track.device_id = selected.device_id
track.load_trkpts(trackbook.database.select_trkpt_start_end(
track.device_id,
selected.device_id,
start_time=(polyline.actualPoints.first() as Trkpt).time,
end_time=(polyline.actualPoints.last() as Trkpt).time,
max_accuracy=PreferencesHelper.load_max_accuracy(),
))
selection_mode = Keys.SELECTION_MODE_STARTSTOP
track.expand_to_trkseg_bounds()
@ -342,13 +371,14 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
when_was_i_here_button.setOnClickListener {
Log.i("VOUSSOIR", "when_was_i_here_button.")
track.load_trkpts(trackbook.database.select_trkpt_bounding_box(
device_id=track.device_id,
device_id=null,
north=mapView.boundingBox.actualNorth,
south=mapView.boundingBox.actualSouth,
east=mapView.boundingBox.lonEast,
west=mapView.boundingBox.lonWest,
max_accuracy=PreferencesHelper.load_max_accuracy(),
))
selection_mode = Keys.SELECTION_MODE_SPATIAL
set_datetimes_from_track()
render_track()
}
@ -414,7 +444,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
dialog.show()
}
deleteButton.setOnClickListener {
delete_whole_track_button.setOnClickListener {
val dialogMessage = "${getString(R.string.dialog_yes_no_message_delete_recording)}\n\n${track.trkpts.size} trackpoints"
YesNoDialog(this@TrackFragment as YesNoDialog.YesNoDialogListener).show(
context = activity as Context,
@ -468,12 +498,78 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
return rootView
}
override fun onDestroyView()
{
super.onDestroyView()
if (gpslistenerregistered)
{
locationManager.removeUpdates(gpsLocationListener)
gpslistenerregistered = false
}
}
fun clear_current_position_overlays()
{
for (ov in current_position_overlays)
{
if (ov in mapView.overlays)
{
mapView.overlays.remove(ov)
}
}
current_position_overlays.clear()
}
fun create_current_position_overlays(location: Location)
{
clear_current_position_overlays()
val newMarker = ContextCompat.getDrawable(requireContext(), R.drawable.ic_marker_location_blue_24dp)!!
val fillcolor = Color.argb(64, 60, 152, 219)
val current_location_radius = Polygon()
current_location_radius.points = Polygon.pointsAsCircle(
GeoPoint(location.latitude, location.longitude),
location.accuracy.toDouble()
)
current_location_radius.fillPaint.color = fillcolor
current_location_radius.outlinePaint.color = Color.argb(0, 0, 0, 0)
current_position_overlays.add(current_location_radius)
val overlayItems: java.util.ArrayList<OverlayItem> = java.util.ArrayList<OverlayItem>()
val overlayItem: OverlayItem = createOverlayItem(
location.latitude,
location.longitude,
title="Current location",
description="Current location",
)
overlayItem.setMarker(newMarker)
overlayItems.add(overlayItem)
current_position_overlays.add(createOverlay(requireContext(), overlayItems))
for (ov in current_position_overlays)
{
mapView.overlays.add(ov)
}
}
/* Overrides onResume from Fragment */
override fun onResume()
{
super.onResume()
}
private fun createLocationListener(): LocationListener
{
return object : LocationListener
{
override fun onLocationChanged(location: Location)
{
create_current_position_overlays(location)
}
}
}
fun select_trkpt(trkpt: Trkpt)
{
selected_trkpt = trkpt
@ -657,6 +753,11 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
{
create_start_end_markers(requireContext(), mapView, pl.actualPoints.first() as Trkpt, pl.actualPoints.last() as Trkpt)
}
for (ov in current_position_overlays)
{
mapView.overlays.add(ov)
}
}
fun new_track_segment_overlay(): Polyline
@ -830,6 +931,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
end_time=get_datetime(track_query_end_date, track_query_end_time, seconds=59).time,
max_accuracy=PreferencesHelper.load_max_accuracy(),
))
selection_mode = Keys.SELECTION_MODE_STARTSTOP
Log.i("VOUSSOIR", "TrackFragment.requery_and_render: Reloaded ${track.trkpts.size} trkpts.")
render_track()
}
@ -863,14 +965,31 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
{
if (type == Keys.DIALOG_DELETE_TRACK && dialogResult && track.trkpts.isNotEmpty())
{
trackbook.database.delete_trkpt_start_end(
track.device_id,
track.trkpts.first().time,
track.trkpts.last().time,
)
trackbook.database.commit()
handler.removeCallbacks(requery_and_render)
handler.postDelayed(requery_and_render, RERENDER_DELAY)
if (selection_mode == Keys.SELECTION_MODE_STARTSTOP)
{
trackbook.database.delete_trkpt_start_end(
track.device_id,
track.trkpts.first().time,
track.trkpts.last().time,
)
trackbook.database.commit()
handler.removeCallbacks(requery_and_render)
handler.postDelayed(requery_and_render, RERENDER_DELAY)
}
else if (selection_mode == Keys.SELECTION_MODE_SPATIAL)
{
// If the user clicked the "when was I here" button to select an area of points, and
// then presses the Track delete button, we don't want to delete all points between
// the earliest start and latest stop -- we just want to delete the points that are
// shown on screen.
for (trkpt in track.trkpts)
{
trackbook.database.delete_trkpt(trkpt)
}
trackbook.database.commit()
handler.removeCallbacks(requery_and_render)
handler.postDelayed(requery_and_render, RERENDER_DELAY)
}
}
}