/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */ /* vim: set et ts=4 sw=4: */ /* * Copyright (c) 2013 Mattias Bengtsson. * * GNOME Maps is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * GNOME Maps is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with GNOME Maps; if not, see . * * Author: Mattias Bengtsson */ import GObject from 'gi://GObject'; import GeocodeGlib from 'gi://GeocodeGlib'; import {Application} from './application.js'; import {PlaceStore} from './placeStore.js'; import {TransitOptions} from './transitOptions.js'; export class QueryPoint extends GObject.Object { constructor() { super(); this._place = null; } set place(p) { this._place = p; this.notify('place'); } get place() { return this._place; } } GObject.registerClass({ Properties: { 'place': GObject.ParamSpec.object('place', '', '', GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE, GeocodeGlib.Place) } }, QueryPoint); export class RouteQuery extends GObject.Object { static MAX_QUERY_POINTS = 10; static Transportation = { CAR: 0, BIKE: 1, PEDESTRIAN: 2, TRANSIT: 3, toString: function (transportation) { switch(transportation) { case RouteQuery.Transportation.CAR: return 'car'; case RouteQuery.Transportation.BIKE: return 'bike'; case RouteQuery.Transportation.PEDESTRIAN: return 'foot'; case RouteQuery.Transportation.TRANSIT: return 'transit'; default: return null; } } } get points() { return this._points; } set points(points) { if (points.length > MAX_QUERY_POINTS) throw new Error('Too many query points'); this._points = points; this.notify('points'); } get filledPoints() { return this.points.filter(function(point) { return point.place; }); } get latest() { return this._latest; } get time() { return this._time; } /* time to leave or arrive, null implies "Leave now" */ set time(time) { this._time = time; this.notify('points'); } get date() { return this._date; } /* date to leave or arrive */ set date(date) { this._date = date; /* only notify change when an actual date was set, when resetting time * time and date (to use "Leave Now" routing) time would be set to null * triggering an update */ if (date) this.notify('points'); } get arriveBy() { return this._arriveBy; } /* when set to true, the set time and date means arrive by the specified * time */ set arriveBy(arriveBy) { this._arriveBy = arriveBy; if (this._time) this.notify('points'); } get transitOptions() { return this._transitOptions; } set transitOptions(options) { this._transitOptions = options; this.notify('points'); } constructor(params) { super(params); this._points = []; this._time = null; this._date = null; this._arriveBy = false; this._transitOptions = new TransitOptions(); this._initTransportation(); this.reset(); } _initTransportation() { let transportationType = Application.settings.get_enum('transportation-type'); this.transportation = transportationType; } addPoint(index) { if (this._points.length >= RouteQuery.MAX_QUERY_POINTS) throw new Error('Too many query points'); let point = new QueryPoint(); if (index === -1) index = this.points.length - 1; this._points.splice(index, 0, point); point.connect('notify::place', () => { let placeStore = Application.placeStore; if (point.place) { if (!placeStore.exists(point.place, null)) { placeStore.addPlace(point.place, PlaceStore.PlaceType.RECENT); } } this.notify('points'); this._latest = point; }); this._latest = point; this.notify('points'); this.emit('point-added', point, index); return point; } removePoint(index) { let removedPoints = this._points.splice(index, 1); let point = removedPoints ? removedPoints[0] : null; if (point === this._latest) this._latest = null; if (point) { this.notify('points'); this.emit('point-removed', point, index); } } set transportation(transportation) { Application.settings.set_enum('transportation-type', transportation); this._transportation = transportation; this.notify('transportation'); this.notify('points'); } get transportation() { return this._transportation; } reset() { this.freeze_notify(); this._points.forEach(function(point) { point.place = null; }); this._latest = null; this.thaw_notify(); this.emit('reset'); } isValid() { if (this.filledPoints.length >= 2 && this.filledPoints.length === this.points.length) return true; else return false; } toString() { return "\nPoints: " + this.points + "\nTransportation: " + this.transportation; } } GObject.registerClass({ Signals: { 'reset': { }, 'point-added': { param_types: [GObject.TYPE_OBJECT, GObject.TYPE_INT] }, 'point-removed': { param_types: [GObject.TYPE_OBJECT, GObject.TYPE_INT] }, 'run': { } }, Properties: { 'points': GObject.ParamSpec.object('points', '', '', GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE, GObject.Object), 'transportation': GObject.ParamSpec.int('transportation', '', '', GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE, RouteQuery.Transportation.CAR, RouteQuery.Transportation.PEDESTRIAN, RouteQuery.Transportation.CAR, RouteQuery.Transportation.TRANSIT) } }, RouteQuery);