Skip to content

preview, edit and delete waypoints (#67, #328) #509

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Feb 18, 2025
5 changes: 4 additions & 1 deletion app/src/main/java/net/osmtracker/activity/TrackLogger.java
Original file line number Diff line number Diff line change
@@ -57,6 +57,7 @@
import java.io.File;
import java.util.Date;
import java.util.HashSet;
import java.util.UUID;


/**
@@ -609,6 +610,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (currentPhotoFile != null && currentPhotoFile.exists()) {
Intent intent = new Intent(OSMTracker.INTENT_TRACK_WP);
intent.putExtra(OSMTracker.INTENT_KEY_UUID, UUID.randomUUID().toString());
intent.putExtra(TrackContentProvider.Schema.COL_TRACK_ID, currentTrackId);
intent.putExtra(OSMTracker.INTENT_KEY_NAME, getResources().getString(R.string.wpt_stillimage));
intent.putExtra(OSMTracker.INTENT_KEY_LINK, currentPhotoFile.getName());
@@ -632,6 +634,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {

// Send an intent to inform service to track the waypoint.
Intent intent = new Intent(OSMTracker.INTENT_TRACK_WP);
intent.putExtra(OSMTracker.INTENT_KEY_UUID, UUID.randomUUID().toString());
intent.putExtra(TrackContentProvider.Schema.COL_TRACK_ID, currentTrackId);
intent.putExtra(OSMTracker.INTENT_KEY_NAME, getResources().getString(R.string.wpt_stillimage));
intent.putExtra(OSMTracker.INTENT_KEY_LINK, destFile.getName());
@@ -778,7 +781,7 @@ private void startCamera() {
*/
private void startGallery() {
Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setType(DataHelper.MIME_TYPE_IMAGE);
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(galleryIntent, REQCODE_GALLERY_CHOSEN);
}
175 changes: 170 additions & 5 deletions app/src/main/java/net/osmtracker/activity/WaypointList.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
package net.osmtracker.activity;

import net.osmtracker.db.TrackContentProvider;
import net.osmtracker.db.WaypointListAdapter;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.ListView;
import androidx.core.content.FileProvider;
import net.osmtracker.R;
import net.osmtracker.db.DataHelper;
import net.osmtracker.db.TrackContentProvider;
import net.osmtracker.db.WaypointListAdapter;
import net.osmtracker.listener.EditWaypointDialogOnClickListener;

import java.io.File;

/**
* Activity that lists the previous waypoints tracked by the user.
@@ -17,6 +32,8 @@
*/
public class WaypointList extends ListActivity {

private static final String TAG = WaypointList.class.getSimpleName();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -29,12 +46,12 @@ protected void onCreate(Bundle savedInstanceState) {
@Override
protected void onResume() {
Long trackId = getIntent().getExtras().getLong(TrackContentProvider.Schema.COL_TRACK_ID);

Cursor cursor = getContentResolver().query(TrackContentProvider.waypointsUri(trackId),
null, null, null, TrackContentProvider.Schema.COL_TIMESTAMP + " desc");
startManagingCursor(cursor);
setListAdapter(new WaypointListAdapter(WaypointList.this, cursor));

super.onResume();
}

@@ -52,4 +69,152 @@ protected void onPause() {
super.onPause();
}

/**
* Handles the selection of a waypoint from the list and opens an edit dialog.
* This dialog allows the user to update the waypoint's name and preview attached files (images or audio).
*
* @param l The ListView where the item was clicked.
* @param v The view that was clicked.
* @param position The position of the clicked item.
* @param id The ID of the clicked waypoint.
*/
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
final Cursor cursor = ((CursorAdapter) getListAdapter()).getCursor();
final DataHelper dataHelper = new DataHelper(l.getContext());
LayoutInflater inflater = this.getLayoutInflater();

// Inflate the waypoint edit dialog layout
final View editWaypointDialog = inflater.inflate(R.layout.edit_waypoint_dialog, null);
final EditText editWaypointName = editWaypointDialog.findViewById(R.id.edit_waypoint_et_name);

Button buttonPreview = editWaypointDialog.findViewById(R.id.edit_waypoint_button_preview);
Button buttonUpdate = editWaypointDialog.findViewById(R.id.edit_waypoint_button_update);
Button buttonDelete = editWaypointDialog.findViewById(R.id.edit_waypoint_button_delete);
Button buttonCancel = editWaypointDialog.findViewById(R.id.edit_waypoint_button_cancel);

// Retrieve existing waypoint name
String oldName = cursor.getString(cursor.getColumnIndex(TrackContentProvider.Schema.COL_NAME));
editWaypointName.setText(oldName);
editWaypointName.setSelection(oldName.length());

// Retrieve waypoint details
final long trackId = cursor.getLong(cursor.getColumnIndex(TrackContentProvider.Schema.COL_TRACK_ID));
final String uuid = cursor.getString(cursor.getColumnIndex(TrackContentProvider.Schema.COL_UUID));
final String link = cursor.getString(cursor.getColumnIndex(TrackContentProvider.Schema.COL_LINK));

final String filePath = (link != null) ? DataHelper.getTrackDirectory(trackId, l.getContext()) + "/" + link : null;
File file = (filePath != null) ? new File(filePath) : null;

if (file != null && file.exists()) {
try {
if (isImageFile(filePath) || isAudioFile(filePath)) {
buttonPreview.setVisibility(View.VISIBLE);
}
} catch (Exception e) {
Log.e(TAG, "Error handling file: " + filePath, e);
}
}

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(true);
AlertDialog alert = builder.create();

// Preview button
buttonPreview.setOnClickListener(new EditWaypointDialogOnClickListener(alert, null) {
@Override
public void onClick(View view) {
if (filePath != null) {
File file = new File(filePath);
Uri fileUri = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) ?
FileProvider.getUriForFile(getApplicationContext(), DataHelper.FILE_PROVIDER_AUTHORITY, file) :
Uri.fromFile(file);

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

if (isImageFile(filePath)) {
intent.setDataAndType(fileUri, DataHelper.MIME_TYPE_IMAGE);
} else if (isAudioFile(filePath)) {
intent.setDataAndType(fileUri, DataHelper.MIME_TYPE_AUDIO);
}

if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
alert.dismiss();
}
});

// Update waypoint name
buttonUpdate.setOnClickListener(new EditWaypointDialogOnClickListener(alert, null) {
@Override
public void onClick(View view) {
String newName = editWaypointName.getText().toString();
dataHelper.updateWayPoint(trackId, uuid, newName, link);
alert.dismiss();
}
});

// Delete waypoint
buttonDelete.setOnClickListener(new EditWaypointDialogOnClickListener(alert, cursor) {
@Override
public void onClick(View view) {
new AlertDialog.Builder(WaypointList.this)
.setTitle(getString(R.string.delete_waypoint_confirm_dialog_title))
.setMessage(getString(R.string.delete_waypoint_confirm_dialog_msg))
.setPositiveButton(getString(R.string.delete_waypoint_confirm_bt_ok), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dataHelper.deleteWayPoint(uuid, filePath);
cursor.requery();
alert.dismiss();
dialog.dismiss();
}
})
.setNegativeButton(getString(R.string.delete_waypoint_confirm_bt_cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.show();
}
});

// Cancel button
buttonCancel.setOnClickListener(new EditWaypointDialogOnClickListener(alert, null) {
@Override
public void onClick(View view) {
alert.dismiss();
}
});

alert.setView(editWaypointDialog);
alert.show();

super.onListItemClick(l, v, position, id);
}

/**
* Checks if a given file path corresponds to an image.
*
* @param path The file path.
* @return True if the file is an image, false otherwise.
*/
private boolean isImageFile(String path) {
return path.endsWith(DataHelper.EXTENSION_JPG);
}

/**
* Checks if a given file path corresponds to an audio file.
*
* @param path The file path.
* @return True if the file is an audio file, false otherwise.
*/
private boolean isAudioFile(String path) {
return path.endsWith(DataHelper.EXTENSION_3GPP);
}

}
44 changes: 21 additions & 23 deletions app/src/main/java/net/osmtracker/db/DataHelper.java
Original file line number Diff line number Diff line change
@@ -58,6 +58,16 @@ public class DataHelper {
*/
public static final String MIME_TYPE_GPX = "application/gpx+xml";

/**
* Audio Files MIME
*/
public static final String MIME_TYPE_AUDIO = "audio/*";

/**
* Image Files MIME
*/
public static final String MIME_TYPE_IMAGE = "image/*";

/**
* APP sign plus FileProvider = authority
*/
@@ -258,16 +268,25 @@ public void updateWayPoint(long trackId, String uuid, String name, String link)
}

/**
* Deletes a waypoint
* Deletes a waypoint and its file associated (if exists)
*
* @param uuid
* Unique ID of the target waypoint
*
* @param filepath
* file attached to the waypoint
*/
public void deleteWayPoint(String uuid) {
public void deleteWayPoint(String uuid, String filepath) {
Log.v(TAG, "Deleting waypoint with uuid '" + uuid);
if (uuid != null) {
contentResolver.delete(Uri.withAppendedPath(TrackContentProvider.CONTENT_URI_WAYPOINT_UUID, uuid), null, null);
}

// delete file if exists
File file = (filepath != null) ? new File(filepath) : null;
if (file != null && file.exists() && file.delete()) {
Log.v(TAG, "File deleted: " + filepath);
}
}


@@ -407,27 +426,6 @@ public static File getTrackDirectory(long trackId, Context context) {
return _return;
}

/* method not in use. TODO: delete code.
public static File getGPXTrackFile(long trackId, ContentResolver contentResolver, Context context) {

String trackName = getTrackNameInDB(trackId, contentResolver);

File sdRoot = Environment.getExternalStorageDirectory();

// The location where the user has specified gpx files and associated content to be written
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String userGPXExportDirectoryName = prefs.getString(
OSMTracker.Preferences.KEY_STORAGE_DIR, OSMTracker.Preferences.VAL_STORAGE_DIR);

// Build storage track path for file creation
String completeGPXTrackPath = sdRoot + userGPXExportDirectoryName.trim() +
File.separator + trackName.trim() + File.separator +
trackName.trim() + DataHelper.EXTENSION_GPX;

return new File(completeGPXTrackPath);
}
*/

public static String getTrackNameInDB(long trackId, ContentResolver contentResolver) {
String trackName = "";
Uri trackUri = ContentUris.withAppendedId(TrackContentProvider.CONTENT_URI_TRACK, trackId);
Original file line number Diff line number Diff line change
@@ -471,7 +471,6 @@ public static final class Schema {
public static final String TBL_TRACKPOINT = "trackpoint";
public static final String TBL_WAYPOINT = "waypoint";
public static final String TBL_TRACK = "track";

public static final String COL_ID = "_id";
public static final String COL_TRACK_ID = "track_id";
public static final String COL_UUID = "uuid";
22 changes: 11 additions & 11 deletions app/src/main/java/net/osmtracker/db/WaypointListAdapter.java
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.RelativeLayout;
import android.widget.TableLayout;
import android.widget.TextView;

/**
@@ -45,32 +46,32 @@ public WaypointListAdapter(Context context, Cursor c) {

@Override
public void bindView(View view, Context context, Cursor cursor) {
RelativeLayout rl = (RelativeLayout) view;
bind(cursor, rl, context);
TableLayout tl = (TableLayout) view;
bind(cursor, tl, context);
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup vg) {
RelativeLayout rl = (RelativeLayout) LayoutInflater.from(vg.getContext()).inflate(R.layout.waypointlist_item,
TableLayout tl = (TableLayout) LayoutInflater.from(vg.getContext()).inflate(R.layout.waypointlist_item,
vg, false);
return bind(cursor, rl, context);
return bind(cursor, tl, context);
}

/**
* Do the binding between data and item view.
*
* @param cursor
* Cursor to pull data
* @param rl
* @param tl
* RelativeView representing one item
* @param context
* Context, to get resources
* @return The relative view with data bound.
*/
private View bind(Cursor cursor, RelativeLayout rl, Context context) {
TextView vName = (TextView) rl.findViewById(R.id.wplist_item_name);
TextView vLocation = (TextView) rl.findViewById(R.id.wplist_item_location);
TextView vTimestamp = (TextView) rl.findViewById(R.id.wplist_item_timestamp);
private View bind(Cursor cursor, TableLayout tl, Context context) {
TextView vName = (TextView) tl.findViewById(R.id.wplist_item_name);
TextView vLocation = (TextView) tl.findViewById(R.id.wplist_item_location);
TextView vTimestamp = (TextView) tl.findViewById(R.id.wplist_item_timestamp);

// Bind name
String name = cursor.getString(cursor.getColumnIndex(TrackContentProvider.Schema.COL_NAME));
@@ -103,8 +104,7 @@ private View bind(Cursor cursor, RelativeLayout rl, Context context) {
// Bind timestamp
Date ts = new Date(cursor.getLong(cursor.getColumnIndex(TrackContentProvider.Schema.COL_TIMESTAMP)));
vTimestamp.setText(DATE_FORMATTER.format(ts));

return rl;
return tl;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package net.osmtracker.listener;

import android.app.AlertDialog;
import android.database.Cursor;
import android.view.View;

/**
* Class that implements an OnClickListener to display an edit waypoint dialog.
*/
public class EditWaypointDialogOnClickListener implements View.OnClickListener {

private Cursor cursor;

protected AlertDialog alert;

protected EditWaypointDialogOnClickListener(AlertDialog alert, Cursor cu) {
this.cursor = cu; // Assigns the received cursor to the class attribute
this.alert = alert; // Assigns the received alert to the class attribute
}

@Override
public void onClick(View view) {
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package net.osmtracker.listener;

import net.osmtracker.OSMTracker;
import net.osmtracker.R;

import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import java.util.UUID;

import net.osmtracker.OSMTracker;
import net.osmtracker.R;
import net.osmtracker.db.TrackContentProvider;


/**
* Listener for standard waypoint tag button.
* Sends an Intent to track waypoint. Waypoint name is the
@@ -36,6 +38,7 @@ public void onClick(View view) {
Intent intent = new Intent(OSMTracker.INTENT_TRACK_WP);
intent.putExtra(TrackContentProvider.Schema.COL_TRACK_ID, currentTrackId);
intent.putExtra(OSMTracker.INTENT_KEY_NAME, label);
intent.putExtra(OSMTracker.INTENT_KEY_UUID, UUID.randomUUID().toString());

String packageName = view.getContext().getPackageName();
intent.setPackage(packageName);
9 changes: 8 additions & 1 deletion app/src/main/java/net/osmtracker/service/gps/GPSLogger.java
Original file line number Diff line number Diff line change
@@ -148,8 +148,15 @@ public void onReceive(Context context, Intent intent) {
// Delete an existing waypoint
Bundle extras = intent.getExtras();
if (extras != null) {
Long trackId = extras.getLong(TrackContentProvider.Schema.COL_TRACK_ID);
String uuid = extras.getString(OSMTracker.INTENT_KEY_UUID);
dataHelper.deleteWayPoint(uuid);
String link = extras.getString(OSMTracker.INTENT_KEY_LINK);
String filePath = null;
try {
filePath = link.equals("null") ? null : DataHelper.getTrackDirectory(trackId, context) + "/" + link;
}
catch(NullPointerException ne){}
dataHelper.deleteWayPoint(uuid, filePath);
}
} else if (OSMTracker.INTENT_START_TRACKING.equals(intent.getAction())) {
Bundle extras = intent.getExtras();
78 changes: 78 additions & 0 deletions app/src/main/res/layout/edit_waypoint_dialog.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:padding="16dp">

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">

<Button
android:id="@+id/edit_waypoint_button_preview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/edit_waypoint_bt_preview"
android:visibility="gone"/>


<!-- Waypoint Name Label -->
<TextView
android:id="@+id/edit_waypoint_tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/waypoint_name_label" />

<!-- EditText -->
<EditText
android:id="@+id/edit_waypoint_et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:padding="10dp"
android:background="@android:drawable/editbox_background"
android:textColor="@color/colorPrimaryDark"
android:textSize="16sp"
android:maxWidth="600dp" />

<!-- Buttons Row -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="8dp">

<Button
android:id="@+id/edit_waypoint_button_update"
style="?android:attr/borderlessButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_weight="1"
android:text="@string/edit_waypoint_bt_save" />

<Button
android:id="@+id/edit_waypoint_button_delete"
style="?android:attr/borderlessButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/edit_waypoint_bt_delete" />
</LinearLayout>


<!-- Cancel Button -->
<Button
android:id="@+id/edit_waypoint_button_cancel"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/edit_waypoint_bt_cancel"
android:gravity="center" />

</LinearLayout>
</ScrollView>
73 changes: 42 additions & 31 deletions app/src/main/res/layout/waypointlist_item.xml
Original file line number Diff line number Diff line change
@@ -1,35 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:stretchColumns="*">

<TableRow
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp">

<TextView
android:id="@+id/wplist_item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="4"
android:text="{name}"
android:textColor="@android:color/holo_green_light"
android:textAppearance="?android:attr/textAppearanceLarge" />

<TextView
android:id="@+id/wplist_item_timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="{timestamp}"
android:gravity="end" />
</TableRow>

<TableRow
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp">

<TextView android:layout_height="wrap_content"
android:id="@+id/wplist_item_name"
android:text="{name}"
android:layout_width="wrap_content"
style="@android:style/TextAppearance.Large">
</TextView>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="{timestamp}"
android:id="@+id/wplist_item_timestamp"
android:layout_below="@+id/wplist_item_location"
android:layout_alignBaseline="@+id/wplist_item_name"
android:layout_alignParentRight="true"
android:layout_alignRight="@+id/wplist_item_name"
android:layout_marginRight="10dp">
</TextView>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/wplist_item_location"
android:text="{location}"
android:layout_below="@+id/wplist_item_name"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp">
</TextView>
<TextView
android:id="@+id/wplist_item_location"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="{location}"
android:layout_span="2"
android:gravity="start" />
</TableRow>

</RelativeLayout>
</TableLayout>
11 changes: 11 additions & 0 deletions app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
@@ -84,6 +84,17 @@
<string name="gpsstatus_record_voicerec">Grabar voz</string>
<string name="gpsstatus_record_stillimage">Tomar foto</string>
<string name="gpsstatus_record_textnote">Nota de texto</string>
<!-- edit_waypoint_dialog -->
<string name="waypoint_name_label">Nombre/contenido del punto</string>
<string name="waypoint_name_hint">Nombre del punto</string>
<string name="edit_waypoint_bt_preview">Abrir archivo</string>
<string name="edit_waypoint_bt_save">Guardar</string>
<string name="edit_waypoint_bt_delete">Eliminar</string>
<string name="edit_waypoint_bt_cancel">Cancelar</string>
<string name="delete_waypoint_confirm_dialog_title">Eliminar punto</string>
<string name="delete_waypoint_confirm_dialog_msg">¿Eliminar este punto?</string>
<string name="delete_waypoint_confirm_bt_ok">Eliminar</string>
<string name="delete_waypoint_confirm_bt_cancel">Cancelar</string>
<!--Menu-->
<string name="menu_settings">Configuración</string>
<string name="menu_waypointlist">Puntos</string>
17 changes: 15 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -84,14 +84,26 @@
<string name="osm_upload_waiting_response">Waiting for OpenStreetMap server response&#8230;</string>
<string name="osm_upload_error">Error while uploading track</string>
<string name="osm_upload_bad_response">The OSM server returned an error: ({0}) message {1}</string>
<string name="osm_upload_unauthorized">Autorization error. Would you like to clear the saved OpenStreetMap credentials?</string>
<string name="osm_upload_unauthorized">Authorization error. Would you like to clear the saved OpenStreetMap credentials?</string>
<string name="osm_upload_sucess">OpenStreetMap upload succeeded</string>

<!-- GPS Status & record bar -->
<string name="gpsstatus_record_voicerec">Voice record</string>
<string name="gpsstatus_record_stillimage">Take photo</string>
<string name="gpsstatus_record_textnote">Text note</string>

<!-- edit_waypoint_dialog -->
<string name="waypoint_name_label">Waypoint Name/text</string>
<string name="waypoint_name_hint">Enter waypoint name</string>
<string name="edit_waypoint_bt_preview">Open file</string>
<string name="edit_waypoint_bt_save">Save</string>
<string name="edit_waypoint_bt_delete">Delete</string>
<string name="edit_waypoint_bt_cancel">Cancel</string>
<string name="delete_waypoint_confirm_dialog_title">Delete waypoint</string>
<string name="delete_waypoint_confirm_dialog_msg">Delete this waypoint?</string>
<string name="delete_waypoint_confirm_bt_ok">Delete</string>
<string name="delete_waypoint_confirm_bt_cancel">Cancel</string>

<!-- Menu -->
<string name="menu_settings">Settings</string>
<string name="menu_waypointlist">Waypoints</string>
@@ -160,7 +172,8 @@
<string name="various_heading">Wait for heading&#8230;</string>
<string name="various_heading_unknown">Heading can\'t be determined</string>
<string name="various_export_finished">Export process finished successfully</string>

<string name="various_waiting_position">Position not available</string>
<string name="various_position_lat_lon">{0} {1} / {2} {3}</string>

<!-- OSM map view -->
<string name="displaytrackmap">OpenStreetMap track display</string>