[gnome-maps/wip/mlundblad/osm-add-location] osmEdit: Add a context menu item for adding locations



commit c3a7992a12ab019824f97712de191e8b4b64edf6
Author: Marcus Lundblad <ml update uu se>
Date:   Sun Jan 31 15:06:03 2016 +0100

    osmEdit: Add a context menu item for adding locations
    
    Launches the OSM edit dialog in add new location mode.
    Offer to zoom in if the zoom level is not one the two
    innermost ones.

 data/org.gnome.Maps.data.gresource.xml |    1 +
 data/ui/context-menu.ui                |    7 ++++
 data/ui/zoom-in-notification.ui        |   25 ++++++++++++++
 po/POTFILES.in                         |    1 +
 src/contextMenu.js                     |   40 ++++++++++++++++++++++
 src/org.gnome.Maps.src.gresource.xml   |    1 +
 src/osmEdit.js                         |   12 +++++++
 src/osmUtils.js                        |    3 ++
 src/zoomInNotification.js              |   57 ++++++++++++++++++++++++++++++++
 9 files changed, 147 insertions(+), 0 deletions(-)
---
diff --git a/data/org.gnome.Maps.data.gresource.xml b/data/org.gnome.Maps.data.gresource.xml
index 36e71bd..d24532c 100644
--- a/data/org.gnome.Maps.data.gresource.xml
+++ b/data/org.gnome.Maps.data.gresource.xml
@@ -32,6 +32,7 @@
     <file preprocess="xml-stripblanks">ui/social-place-row.ui</file>
     <file preprocess="xml-stripblanks">ui/user-location-bubble.ui</file>
     <file preprocess="xml-stripblanks">ui/zoom-control.ui</file>
+    <file preprocess="xml-stripblanks">ui/zoom-in-notification.ui</file>
     <file alias="application.css">gnome-maps.css</file>
     <file alias="ui/maptype-aerial.png">media/maptype-aerial.png</file>
     <file alias="ui/maptype-street.png">media/maptype-street.png</file>
diff --git a/data/ui/context-menu.ui b/data/ui/context-menu.ui
index eb2c7c8..90ce436 100644
--- a/data/ui/context-menu.ui
+++ b/data/ui/context-menu.ui
@@ -30,5 +30,12 @@
         <property name="visible">True</property>
       </object>
     </child>
+    <child>
+      <object class="GtkMenuItem" id="addOSMLocationItem">
+        <property name="name">add-osm-location-item</property>
+        <property name="label" translatable="yes">Add Location</property>
+        <property name="visible">True</property>
+      </object>
+    </child>
   </template>
 </interface>
diff --git a/data/ui/zoom-in-notification.ui b/data/ui/zoom-in-notification.ui
new file mode 100644
index 0000000..818302d
--- /dev/null
+++ b/data/ui/zoom-in-notification.ui
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <object class="GtkGrid" id="grid">
+    <property name="visible">True</property>
+    <property name="hexpand">False</property>
+    <property name="orientation">horizontal</property>
+    <child>
+      <object class="GtkLabel" id="label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin-end">30</property>
+        <property name="label" translatable="yes">You need to be zoomed-in to edit!</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkButton" id="zoomInButton">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Zoom</property>
+        <property name="focus-on-click">False</property>
+        <property name="margin-end">5</property>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index c60da7f..adeeb42 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -20,6 +20,7 @@ data/org.gnome.Maps.gschema.xml
 [type: gettext/glade]data/ui/sidebar.ui
 [type: gettext/glade]data/ui/social-place-more-results-row.ui
 [type: gettext/glade]data/ui/user-location-bubble.ui
+[type: gettext/glade]data/ui/zoom-in-notification.ui
 lib/maps-file-tile-source.c
 lib/maps-osm.c
 src/application.js
diff --git a/src/contextMenu.js b/src/contextMenu.js
index 7560adc..2621876 100644
--- a/src/contextMenu.js
+++ b/src/contextMenu.js
@@ -30,8 +30,13 @@ const Application = imports.application;
 const ExportViewDialog = imports.exportViewDialog;
 const Lang = imports.lang;
 const Location = imports.location;
+const OSMAccountDialog = imports.osmAccountDialog;
+const OSMEdit = imports.osmEdit;
+const OSMEditDialog = imports.osmEditDialog;
+const OSMUtils = imports.osmUtils;
 const Place = imports.place;
 const Utils = imports.utils;
+const ZoomInNotification = imports.zoomInNotification;
 
 const ContextMenu = new Lang.Class({
     Name: 'ContextMenu',
@@ -40,6 +45,7 @@ const ContextMenu = new Lang.Class({
     InternalChildren: [ 'whatsHereItem',
                         'geoURIItem',
                         'exportItem',
+                        'addOSMLocationItem',
                         'routeItem' ],
 
     _init: function(params) {
@@ -57,6 +63,8 @@ const ContextMenu = new Lang.Class({
                                  this._onGeoURIActivated.bind(this));
         this._exportItem.connect('activate',
                                  this._onExportActivated.bind(this));
+        this._addOSMLocationItem.connect('activate',
+                                         this._onAddOSMLocationActivated.bind(this));
         this._routeItem.connect('activate',
                                 this._onRouteActivated.bind(this));
         Application.routeService.query.connect('notify::points',
@@ -132,6 +140,38 @@ const ContextMenu = new Lang.Class({
         clipboard.set_text(uri, uri.length);
     },
 
+    _onAddOSMLocationActivated: function() {
+        let osmEdit = Application.osmEdit;
+        /* if the user is not alread signed in, show the account dialog */
+        if (!osmEdit.isSignedIn) {
+            let response = osmEdit.showAccountDialog(this.get_toplevel(), true);
+            if (!response === OSMAccountDialog.Response.SIGNED_IN)
+                return;
+        }
+
+        /* if the user is not sufficently zoomed-in, show a notification
+           offering to zoom in */
+        if (this._mapView.view.get_zoom_level() < OSMUtils.MIN_ADD_LOCATION_ZOOM_LEVEL) {
+            let zoomInNotification =
+                new ZoomInNotification.ZoomInNotification({longitude: this._longitude,
+                                                           latitude: this._latitude,
+                                                           view: this._mapView.view});
+            Application.notificationManager.showNotification(zoomInNotification);
+            return;
+        }
+
+        let response =
+            osmEdit.showEditNewDialog(this.get_toplevel(),
+                                      this._latitude, this._longitude);
+        /* TODO: should we create a location in the location store, and maybe
+           show a place marker (on success)? */
+        if (response === OSMEditDialog.Response.UPLOADED) {
+            /* show a notification on success */
+            Application.notificationManager.showMessage(
+                _("Location was added to the map, note that it may take a while before it shows on the map 
and in search results."));
+        }
+    },
+
     _activateExport: function() {
         let view = this._mapView.view;
         let surface = view.to_surface(true);
diff --git a/src/org.gnome.Maps.src.gresource.xml b/src/org.gnome.Maps.src.gresource.xml
index 17cc54c..0a96fde 100644
--- a/src/org.gnome.Maps.src.gresource.xml
+++ b/src/org.gnome.Maps.src.gresource.xml
@@ -70,6 +70,7 @@
     <file>userLocationMarker.js</file>
     <file>utils.js</file>
     <file>zoomControl.js</file>
+    <file>zoomInNotification.js</file>
     <file alias="geojsonvt/clip.js">clip.js</file>
     <file alias="geojsonvt/convert.js">convert.js</file>
     <file alias="geojsonvt/geojsonvt.js">index.js</file>
diff --git a/src/osmEdit.js b/src/osmEdit.js
index 62f15d5..5d911c6 100644
--- a/src/osmEdit.js
+++ b/src/osmEdit.js
@@ -54,6 +54,18 @@ const OSMEdit = new Lang.Class({
         return response;
     },
 
+    showEditNewDialog: function(parentWindow, latitude, longitude) {
+        let dialog = new OSMEditDialog.OSMEditDialog({
+            transient_for: parentWindow,
+            addLocation: true,
+            latitude: latitude,
+            longitude: longitude
+        });
+        let response = dialog.run();
+        dialog.destroy();
+        return response;
+    },
+
     showAccountDialog: function(parentWindow, closeOnSignIn) {
         let dialog = new OSMAccountDialog.OSMAccountDialog({
             transient_for: parentWindow,
diff --git a/src/osmUtils.js b/src/osmUtils.js
index 4c2f183..d2735e1 100644
--- a/src/osmUtils.js
+++ b/src/osmUtils.js
@@ -24,6 +24,9 @@ const Soup = imports.gi.Soup;
 
 const Application = imports.application;
 
+/* minimum zoom level at which to offer adding a location */
+const MIN_ADD_LOCATION_ZOOM_LEVEL = 16;
+
 /*
  * Gets a Wikipedia article in OSM tag format (i.e. lang:Article title)
  * given a URL or null if input doesn't match a Wikipedia URL
diff --git a/src/zoomInNotification.js b/src/zoomInNotification.js
new file mode 100644
index 0000000..d29fc22
--- /dev/null
+++ b/src/zoomInNotification.js
@@ -0,0 +1,57 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2016 Marcus Lundblad.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Author: Marcus Lundblad <ml update uu se>
+ */
+
+const Lang = imports.lang;
+
+const Application = imports.application;
+const Notification = imports.notification;
+const OSMUtils = imports.osmUtils;
+const Utils = imports.utils;
+
+const ZoomInNotification = Lang.Class({
+    Name: 'ZoomInNotification',
+    Extends: Notification.Notification,
+    InternalChildren: ['zoomInButton'],
+
+    _init: function(props) {
+        this._latitude = props.latitude;
+        this._longitude = props.longitude;
+        this._view = props.view;
+        this.parent();
+
+        let ui = Utils.getUIObject('zoom-in-notification', [ 'grid',
+                                                             'zoomInButton' ]);
+
+        ui.zoomInButton.connect('clicked', this._onZoomIn.bind(this));
+
+        this._ui.body.add(ui.grid);
+    },
+
+    _onZoomIn: function() {
+        /* zoom in to the inner-most level */
+        this._view.zoom_level = OSMUtils.MIN_ADD_LOCATION_ZOOM_LEVEL;
+
+        /* center on the position first selected */
+        this._view.center_on(this._latitude, this._longitude);
+        this.dismiss();
+    }
+})
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]