Convert Place to Kotlin

pull/996/head
Alex Baker 4 years ago
parent 9a1058c563
commit d4d4053ec1

@ -68,7 +68,7 @@ class LocationDaoTest : InjectingTestCase() {
taskDao.createNew(newTask(with(ID, 1)))
locationDao.insert(newGeofence(with(TASK, 1), with(PLACE, place.uid)))
assertNull(locationDao.getGeofencesByPlace(place.uid))
assertNull(locationDao.getGeofencesByPlace(place.uid!!))
}
@Test
@ -78,7 +78,7 @@ class LocationDaoTest : InjectingTestCase() {
taskDao.createNew(newTask(with(ID, 1)))
locationDao.insert(newGeofence(with(TASK, 1), with(PLACE, place.uid), with(ARRIVAL, true)))
val geofence = locationDao.getGeofencesByPlace(place.uid)
val geofence = locationDao.getGeofencesByPlace(place.uid!!)
assertTrue(geofence!!.arrival)
assertFalse(geofence.departure)
@ -91,7 +91,7 @@ class LocationDaoTest : InjectingTestCase() {
taskDao.createNew(newTask(with(ID, 1)))
locationDao.insert(newGeofence(with(TASK, 1), with(PLACE, place.uid), with(DEPARTURE, true)))
val geofence = locationDao.getGeofencesByPlace(place.uid)
val geofence = locationDao.getGeofencesByPlace(place.uid!!)
assertFalse(geofence!!.arrival)
assertTrue(geofence.departure)
@ -104,7 +104,7 @@ class LocationDaoTest : InjectingTestCase() {
taskDao.createNew(newTask(with(ID, 1), with(COMPLETION_TIME, newDateTime())))
locationDao.insert(newGeofence(with(TASK, 1), with(PLACE, place.uid), with(ARRIVAL, true)))
assertNull(locationDao.getGeofencesByPlace(place.uid))
assertNull(locationDao.getGeofencesByPlace(place.uid!!))
}
@Test
@ -114,7 +114,7 @@ class LocationDaoTest : InjectingTestCase() {
taskDao.createNew(newTask(with(ID, 1), with(DELETION_TIME, newDateTime())))
locationDao.insert(newGeofence(with(TASK, 1), with(PLACE, place.uid), with(ARRIVAL, true)))
assertNull(locationDao.getGeofencesByPlace(place.uid))
assertNull(locationDao.getGeofencesByPlace(place.uid!!))
}
@Test
@ -125,7 +125,7 @@ class LocationDaoTest : InjectingTestCase() {
taskDao.createNew(newTask(with(ID, 1), with(SNOOZE_TIME, newDateTime().plusMinutes(15))))
locationDao.insert(newGeofence(with(TASK, 1), with(PLACE, place.uid), with(ARRIVAL, true)))
assertTrue(locationDao.getArrivalGeofences(place.uid, now()).isEmpty())
assertTrue(locationDao.getArrivalGeofences(place.uid!!, now()).isEmpty())
}
}
@ -137,7 +137,7 @@ class LocationDaoTest : InjectingTestCase() {
taskDao.createNew(newTask(with(ID, 1), with(SNOOZE_TIME, newDateTime().plusMinutes(15))))
locationDao.insert(newGeofence(with(TASK, 1), with(PLACE, place.uid), with(DEPARTURE, true)))
assertTrue(locationDao.getDepartureGeofences(place.uid, now()).isEmpty())
assertTrue(locationDao.getDepartureGeofences(place.uid!!, now()).isEmpty())
}
}
@ -150,7 +150,7 @@ class LocationDaoTest : InjectingTestCase() {
val geofence = newGeofence(with(TASK, 1), with(PLACE, place.uid), with(ARRIVAL, true))
geofence.id = locationDao.insert(geofence)
assertEquals(listOf(geofence), locationDao.getArrivalGeofences(place.uid, now()))
assertEquals(listOf(geofence), locationDao.getArrivalGeofences(place.uid!!, now()))
}
}
@ -163,7 +163,7 @@ class LocationDaoTest : InjectingTestCase() {
val geofence = newGeofence(with(TASK, 1), with(PLACE, place.uid), with(DEPARTURE, true))
geofence.id = locationDao.insert(geofence)
assertEquals(listOf(geofence), locationDao.getDepartureGeofences(place.uid, now()))
assertEquals(listOf(geofence), locationDao.getDepartureGeofences(place.uid!!, now()))
}
}
@ -178,7 +178,7 @@ class LocationDaoTest : InjectingTestCase() {
with(HIDE_TYPE, Task.HIDE_UNTIL_DUE_TIME)))
locationDao.insert(newGeofence(with(TASK, 1), with(PLACE, place.uid), with(ARRIVAL, true)))
assertTrue(locationDao.getArrivalGeofences(place.uid, now()).isEmpty())
assertTrue(locationDao.getArrivalGeofences(place.uid!!, now()).isEmpty())
}
}
@ -193,7 +193,7 @@ class LocationDaoTest : InjectingTestCase() {
with(HIDE_TYPE, Task.HIDE_UNTIL_DUE_TIME)))
locationDao.insert(newGeofence(with(TASK, 1), with(PLACE, place.uid), with(DEPARTURE, true)))
assertTrue(locationDao.getDepartureGeofences(place.uid, now()).isEmpty())
assertTrue(locationDao.getDepartureGeofences(place.uid!!, now()).isEmpty())
}
}
@ -209,7 +209,7 @@ class LocationDaoTest : InjectingTestCase() {
val geofence = newGeofence(with(TASK, 1), with(PLACE, place.uid), with(ARRIVAL, true))
geofence.id = locationDao.insert(geofence)
assertEquals(listOf(geofence), locationDao.getArrivalGeofences(place.uid, now()))
assertEquals(listOf(geofence), locationDao.getArrivalGeofences(place.uid!!, now()))
}
}
@ -225,7 +225,7 @@ class LocationDaoTest : InjectingTestCase() {
val geofence = newGeofence(with(TASK, 1), with(PLACE, place.uid), with(DEPARTURE, true))
geofence.id = locationDao.insert(geofence)
assertEquals(listOf(geofence), locationDao.getDepartureGeofences(place.uid, now()))
assertEquals(listOf(geofence), locationDao.getDepartureGeofences(place.uid!!, now()))
}
}

@ -50,7 +50,7 @@ class PlaceSettingsActivity : BaseListSettingsActivity(), MapFragment.MapFragmen
if (savedInstanceState == null) {
name.setText(place.displayName)
selectedColor = place.color
selectedIcon = place.icon
selectedIcon = place.getIcon()!!
}
map.init(supportFragmentManager, this, theme.themeBase.isDarkTheme(this))
@ -62,7 +62,7 @@ class PlaceSettingsActivity : BaseListSettingsActivity(), MapFragment.MapFragmen
override fun hasChanges() = name.text.toString() != place.displayName
|| selectedColor != place.color
|| selectedIcon != place.icon
|| selectedIcon != place.getIcon()!!
@OnTextChanged(R.id.name)
fun onNameChanged() {
@ -79,7 +79,7 @@ class PlaceSettingsActivity : BaseListSettingsActivity(), MapFragment.MapFragmen
place.name = newName
place.color = selectedColor
place.icon = selectedIcon
place.setIcon(selectedIcon)
locationDao.update(place)
setResult(
Activity.RESULT_OK,
@ -90,12 +90,12 @@ class PlaceSettingsActivity : BaseListSettingsActivity(), MapFragment.MapFragmen
override fun isNew() = false
override fun getToolbarTitle(): String {
override fun getToolbarTitle(): String? {
return place.address ?: place.displayName
}
override fun delete() {
locationDao.deleteGeofencesByPlace(place.uid)
locationDao.deleteGeofencesByPlace(place.uid!!)
locationDao.delete(place)
setResult(Activity.RESULT_OK, Intent(TaskListFragment.ACTION_DELETED))
finish()

@ -37,10 +37,10 @@ class Location : Serializable, Parcelable {
val radius: Int
get() = geofence.radius
val phone: String
val phone: String?
get() = place.phone
val url: String
val url: String?
get() = place.url
val isArrival: Boolean
@ -49,10 +49,10 @@ class Location : Serializable, Parcelable {
val isDeparture: Boolean
get() = geofence.isDeparture
val displayName: String
val displayName: String?
get() = place.displayName
val displayAddress: String
val displayAddress: String?
get() = place.displayAddress
fun open(context: Context?) {

@ -8,7 +8,7 @@ class MergedGeofence {
var departure = false
var radius = 0
val uid: String
val uid: String?
get() = place.uid
val latitude: Double

@ -1,371 +0,0 @@
package org.tasks.data;
import static com.mapbox.api.geocoding.v5.GeocodingCriteria.TYPE_ADDRESS;
import static org.tasks.Strings.isNullOrEmpty;
import static org.tasks.data.Place.TABLE_NAME;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.location.Location;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.Index;
import androidx.room.PrimaryKey;
import com.mapbox.api.geocoding.v5.models.CarmenFeature;
import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.andlib.data.Table;
import com.todoroo.astrid.helper.UUIDHelper;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.fortuna.ical4j.model.property.Geo;
import org.tasks.R;
import org.tasks.location.MapPosition;
import org.tasks.themes.CustomIcons;
@Entity(tableName = TABLE_NAME, indices = @Index(name = "place_uid", value = "uid", unique = true))
public class Place implements Serializable, Parcelable {
public static final String KEY = "place";
static final String TABLE_NAME = "places";
public static final Table TABLE = new Table(TABLE_NAME);
public static final StringProperty UID = new StringProperty(TABLE, "uid");
public static final Parcelable.Creator<Place> CREATOR =
new Parcelable.Creator<Place>() {
@Override
public Place createFromParcel(Parcel source) {
return new Place(source);
}
@Override
public Place[] newArray(int size) {
return new Place[size];
}
};
private static final Pattern pattern = Pattern.compile("(\\d+):(\\d+):(\\d+\\.\\d+)");
private static final Pattern COORDS =
Pattern.compile("^\\d+°\\d+'\\d+\\.\\d+\"[NS] \\d+°\\d+'\\d+\\.\\d+\"[EW]$");
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "place_id")
private transient long id;
@ColumnInfo(name = "uid")
private String uid;
@ColumnInfo(name = "name")
private String name;
@ColumnInfo(name = "address")
private String address;
@ColumnInfo(name = "phone")
private String phone;
@ColumnInfo(name = "url")
private String url;
@ColumnInfo(name = "latitude")
private double latitude;
@ColumnInfo(name = "longitude")
private double longitude;
@ColumnInfo(name = "place_color")
private int color;
@ColumnInfo(name = "place_icon")
private int icon = -1;
public Place() {}
@Ignore
public Place(Place o) {
id = o.id;
uid = o.uid;
name = o.name;
address = o.address;
phone = o.phone;
url = o.url;
latitude = o.latitude;
longitude = o.longitude;
color = o.color;
icon = o.icon;
}
@Ignore
public Place(Parcel parcel) {
id = parcel.readLong();
uid = parcel.readString();
name = parcel.readString();
address = parcel.readString();
phone = parcel.readString();
url = parcel.readString();
latitude = parcel.readDouble();
longitude = parcel.readDouble();
color = parcel.readInt();
icon = parcel.readInt();
}
private static String formatCoordinate(double coordinates, boolean latitude) {
String output =
android.location.Location.convert(Math.abs(coordinates), Location.FORMAT_SECONDS);
Matcher matcher = pattern.matcher(output);
if (matcher.matches()) {
return String.format(
"%s°%s'%s\"%s",
matcher.group(1),
matcher.group(2),
matcher.group(3),
latitude ? (coordinates > 0 ? "N" : "S") : (coordinates > 0 ? "E" : "W"));
} else {
return Double.toString(coordinates);
}
}
public static Place newPlace(Geo geo) {
Place place = newPlace();
place.setLatitude(geo.getLatitude().doubleValue());
place.setLongitude(geo.getLongitude().doubleValue());
return place;
}
@Nullable
public static Place newPlace(@Nullable MapPosition mapPosition) {
if (mapPosition == null) {
return null;
}
Place place = newPlace();
place.setLatitude(mapPosition.getLatitude());
place.setLongitude(mapPosition.getLongitude());
return place;
}
public static Place newPlace(CarmenFeature feature) {
String address = feature.placeName();
List<String> types = feature.placeType();
Place place = newPlace();
place.setName(
types != null && types.contains(TYPE_ADDRESS)
? String.format("%s %s", feature.address(), feature.text())
: feature.text());
place.setAddress(address);
place.setLatitude(feature.center().latitude());
place.setLongitude(feature.center().longitude());
return place;
}
public static Place newPlace() {
Place place = new Place();
place.setUid(UUIDHelper.newUUID());
return place;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
@Nullable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public int getIcon() {
return icon == -1 ? CustomIcons.getPLACE() : icon;
}
public void setIcon(int icon) {
this.icon = icon;
}
public String getDisplayName() {
if (!isNullOrEmpty(name) && !COORDS.matcher(name).matches()) {
return name;
}
if (!isNullOrEmpty(address)) {
return address;
}
return String.format(
"%s %s", formatCoordinate(getLatitude(), true), formatCoordinate(getLongitude(), false));
}
public String getDisplayAddress() {
return isNullOrEmpty(address) ? null : address.replace(String.format("%s, ", name), "");
}
public void open(Context context) {
if (context == null) {
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(getGeoUri()));
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
if (resolveInfos.isEmpty()) {
Toast.makeText(context, R.string.no_application_found_link, Toast.LENGTH_SHORT).show();
} else {
context.startActivity(intent);
}
}
private String getGeoUri() {
return String.format("geo:%s,%s?q=%s", latitude, longitude, Uri.encode(getDisplayName()));
}
public MapPosition getMapPosition() {
return new MapPosition(latitude, longitude);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Place)) {
return false;
}
Place place = (Place) o;
return id == place.id
&& Double.compare(place.latitude, latitude) == 0
&& Double.compare(place.longitude, longitude) == 0
&& color == place.color
&& icon == place.icon
&& Objects.equals(uid, place.uid)
&& Objects.equals(name, place.name)
&& Objects.equals(address, place.address)
&& Objects.equals(phone, place.phone)
&& Objects.equals(url, place.url);
}
@Override
public int hashCode() {
return Objects.hash(id, uid, name, address, phone, url, latitude, longitude, color, icon);
}
@Override
public String toString() {
return "Place{"
+ "id="
+ id
+ ", uid='"
+ uid
+ '\''
+ ", name='"
+ name
+ '\''
+ ", address='"
+ address
+ '\''
+ ", phone='"
+ phone
+ '\''
+ ", url='"
+ url
+ '\''
+ ", latitude="
+ latitude
+ ", longitude="
+ longitude
+ ", color="
+ color
+ ", icon="
+ icon
+ '}';
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeLong(id);
out.writeString(uid);
out.writeString(name);
out.writeString(address);
out.writeString(phone);
out.writeString(url);
out.writeDouble(latitude);
out.writeDouble(longitude);
out.writeInt(color);
out.writeInt(icon);
}
}

@ -0,0 +1,250 @@
package org.tasks.data
import android.content.Context
import android.content.Intent
import android.location.Location
import android.net.Uri
import android.os.Parcel
import android.os.Parcelable
import android.widget.Toast
import androidx.room.*
import com.mapbox.api.geocoding.v5.GeocodingCriteria
import com.mapbox.api.geocoding.v5.models.CarmenFeature
import com.todoroo.andlib.data.Property.StringProperty
import com.todoroo.andlib.data.Table
import com.todoroo.astrid.helper.UUIDHelper
import net.fortuna.ical4j.model.property.Geo
import org.tasks.R
import org.tasks.Strings
import org.tasks.location.MapPosition
import org.tasks.themes.CustomIcons.PLACE
import java.io.Serializable
import java.util.regex.Pattern
import kotlin.math.abs
@Entity(tableName = Place.TABLE_NAME, indices = [Index(name = "place_uid", value = ["uid"], unique = true)])
class Place : Serializable, Parcelable {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "place_id")
@Transient
var id: Long = 0
@ColumnInfo(name = "uid")
var uid: String? = null
@ColumnInfo(name = "name")
var name: String? = null
@ColumnInfo(name = "address")
var address: String? = null
@ColumnInfo(name = "phone")
var phone: String? = null
@ColumnInfo(name = "url")
var url: String? = null
@ColumnInfo(name = "latitude")
var latitude = 0.0
@ColumnInfo(name = "longitude")
var longitude = 0.0
@ColumnInfo(name = "place_color")
var color = 0
@ColumnInfo(name = "place_icon")
private var icon = -1
constructor()
@Ignore
constructor(o: Place) {
id = o.id
uid = o.uid
name = o.name
address = o.address
phone = o.phone
url = o.url
latitude = o.latitude
longitude = o.longitude
color = o.color
icon = o.icon
}
@Ignore
constructor(parcel: Parcel) {
id = parcel.readLong()
uid = parcel.readString()
name = parcel.readString()
address = parcel.readString()
phone = parcel.readString()
url = parcel.readString()
latitude = parcel.readDouble()
longitude = parcel.readDouble()
color = parcel.readInt()
icon = parcel.readInt()
}
fun getIcon(): Int? {
return if (icon == -1) PLACE else icon
}
fun setIcon(icon: Int) {
this.icon = icon
}
val displayName: String?
get() {
if (!Strings.isNullOrEmpty(name) && !COORDS.matcher(name!!).matches()) {
return name
}
return if (!Strings.isNullOrEmpty(address)) {
address
} else {
"${formatCoordinate(latitude, true)} ${formatCoordinate(longitude, false)}"
}
}
val displayAddress: String?
get() = if (Strings.isNullOrEmpty(address)) null else address!!.replace("$name, ", "")
fun open(context: Context?) {
if (context == null) {
return
}
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("geo:$latitude,$longitude?q=${Uri.encode(displayName)}")
val pm = context.packageManager
val resolveInfos = pm.queryIntentActivities(intent, 0)
if (resolveInfos.isEmpty()) {
Toast.makeText(context, R.string.no_application_found_link, Toast.LENGTH_SHORT).show()
} else {
context.startActivity(intent)
}
}
val mapPosition: MapPosition
get() = MapPosition(latitude, longitude)
override fun describeContents() = 0
override fun writeToParcel(out: Parcel, flags: Int) {
out.writeLong(id)
out.writeString(uid)
out.writeString(name)
out.writeString(address)
out.writeString(phone)
out.writeString(url)
out.writeDouble(latitude)
out.writeDouble(longitude)
out.writeInt(color)
out.writeInt(icon)
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Place) return false
if (id != other.id) return false
if (uid != other.uid) return false
if (name != other.name) return false
if (address != other.address) return false
if (phone != other.phone) return false
if (url != other.url) return false
if (latitude != other.latitude) return false
if (longitude != other.longitude) return false
if (color != other.color) return false
if (icon != other.icon) return false
return true
}
override fun hashCode(): Int {
var result = id.hashCode()
result = 31 * result + (uid?.hashCode() ?: 0)
result = 31 * result + (name?.hashCode() ?: 0)
result = 31 * result + (address?.hashCode() ?: 0)
result = 31 * result + (phone?.hashCode() ?: 0)
result = 31 * result + (url?.hashCode() ?: 0)
result = 31 * result + latitude.hashCode()
result = 31 * result + longitude.hashCode()
result = 31 * result + color
result = 31 * result + icon
return result
}
override fun toString(): String {
return "Place(id=$id, uid=$uid, name=$name, address=$address, phone=$phone, url=$url, latitude=$latitude, longitude=$longitude, color=$color, icon=$icon)"
}
companion object {
const val KEY = "place"
const val TABLE_NAME = "places"
@JvmField val TABLE = Table(TABLE_NAME)
@JvmField val UID = StringProperty(TABLE, "uid")
@JvmField val CREATOR: Parcelable.Creator<Place> = object : Parcelable.Creator<Place> {
override fun createFromParcel(source: Parcel): Place? {
return Place(source)
}
override fun newArray(size: Int): Array<Place?> {
return arrayOfNulls(size)
}
}
private val pattern = Pattern.compile("(\\d+):(\\d+):(\\d+\\.\\d+)")
private val COORDS = Pattern.compile("^\\d+°\\d+'\\d+\\.\\d+\"[NS] \\d+°\\d+'\\d+\\.\\d+\"[EW]$")
private fun formatCoordinate(coordinates: Double, latitude: Boolean): String {
val output = Location.convert(abs(coordinates), Location.FORMAT_SECONDS)
val matcher = pattern.matcher(output)
return if (matcher.matches()) {
val direction = if (latitude) {
if (coordinates > 0) "N" else "S"
} else {
if (coordinates > 0) "E" else "W"
}
"${matcher.group(1)}°${matcher.group(2)}'${matcher.group(3)}\"$direction"
} else {
coordinates.toString()
}
}
@JvmStatic fun newPlace(geo: Geo): Place {
val place = newPlace()
place.latitude = geo.latitude.toDouble()
place.longitude = geo.longitude.toDouble()
return place
}
@JvmStatic fun newPlace(mapPosition: MapPosition?): Place? {
if (mapPosition == null) {
return null
}
val place = newPlace()
place.latitude = mapPosition.latitude
place.longitude = mapPosition.longitude
return place
}
@JvmStatic fun newPlace(feature: CarmenFeature): Place {
val address = feature.placeName()
val types = feature.placeType()
val place = newPlace()
place.name = if (types != null && types.contains(GeocodingCriteria.TYPE_ADDRESS)) {
"${feature.address()} ${feature.text()}"
} else {
feature.text()
}
place.address = address
place.latitude = feature.center()!!.latitude()
place.longitude = feature.center()!!.longitude()
return place
}
@JvmStatic fun newPlace(): Place {
val place = Place()
place.uid = UUIDHelper.newUUID()
return place
}
}
}

@ -10,7 +10,7 @@ class PlaceUsage {
get() = place.color
val icon: Int
get() = place.icon
get() = place.getIcon()!!
override fun equals(other: Any?): Boolean {
if (this === other) return true

Loading…
Cancel
Save