Commit 9ec57f6d authored by Jonas Danielsson's avatar Jonas Danielsson
Browse files

Merge branch 'fixup' into wip/map-widget

	src/contacts-app.vala
parents b8fb5453 2bc3aae0
......@@ -50,10 +50,12 @@ pkg_modules="gtk+-3.0 >= 3.12.0
libedataserver-1.2 >= 3.5.3
goa-1.0
gee-0.8
champlain-gtk-0.12
geocode-glib-1.0
"
PKG_CHECK_MODULES(CONTACTS, [$pkg_modules])
CONTACTS_PACKAGES="--pkg gtk+-3.0 --pkg gio-2.0 --pkg gio-unix-2.0 --pkg folks --pkg folks-telepathy --pkg folks-eds --pkg libnotify"
CONTACTS_PACKAGES="--pkg gtk+-3.0 --pkg gio-2.0 --pkg gio-unix-2.0 --pkg folks --pkg folks-telepathy --pkg folks-eds --pkg libnotify --pkg clutter-1.0 --pkg champlain-0.12 --pkg champlain-gtk-0.12 --pkg geocode-glib-1.0"
AC_SUBST(CONTACTS_PACKAGES)
# Optional dependency for the user accounts panel
......
......@@ -37,6 +37,7 @@ EXTRA_DIST = \
org.gnome.Contacts.search-provider.ini.in.in \
contacts.gresource.xml \
ui/app-menu.ui \
ui/contacts-address-map.ui \
ui/contacts-window.ui \
ui/contacts-list-pane.ui \
ui/style.css \
......
......@@ -3,6 +3,7 @@
<gresource prefix="/org/gnome/contacts">
<file compressed="true">ui/style.css</file>
<file compressed="true" preprocess="xml-stripblanks">ui/app-menu.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/contacts-address-map.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/contacts-window.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/contacts-list-pane.ui</file>
</gresource>
......
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.10 -->
<template class="ContactsAddressMap" parent="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">False</property>
<property name="hexpand_set">True</property>
<property name="shadow_type">in</property>
<property name="width_request">300</property>
<property name="height_request">300</property>
<style>
<class name="contacts-map"/>
</style>
<child>
<object class="GtkStack" id="map_stack">
<property name="visible">True</property>
<child>
<object class="GtkImage" id="map_icon">
<property name="name">mark-location-image</property>
<property name="visible">True</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="icon-name">mark-location-symbolic</property>
<property name="pixel-size">48</property>
</object>
</child>
<child>
<object class="GtkGrid" id="map_grid">
<property name="orientation">vertical</property>
<property name="visible">True</property>
</object>
</child>
</object>
</child>
</template>
</interface>
......@@ -10,6 +10,11 @@ ContactsListPane.frame:dir(rtl) {
border-width: 0 0 0 1px;
}
.contacts-map {
background-color: @theme_bg_color;
color: gray;
}
/* contatcs view new color */
.contacts-view {
background-color: transparent;
......
......@@ -25,6 +25,7 @@ bin_PROGRAMS = gnome-contacts
vala_sources = \
contacts-app.vala \
contacts-address-map.vala \
contacts-contact.vala \
contacts-contact-sheet.vala \
contacts-contact-editor.vala \
......
/* -*- Mode: vala; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 8 -*- */
/*
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Champlain;
using Folks;
using Geocode;
using Gee;
using Gtk;
using GtkChamplain;
[GtkTemplate (ui = "/org/gnome/contacts/ui/contacts-address-map.ui")]
public class Contacts.AddressMap : Frame {
[GtkChild]
private Stack map_stack;
[GtkChild]
private Grid map_grid;
[GtkChild]
private Gtk.Image map_icon;
private Set<PostalAddressFieldDetails> addresses;
private GLib.List<Place> found_places;
private Champlain.View map_view;
private MarkerLayer marker_layer;
private Mutex mutex;
private ulong alloc_id = 0;
public AddressMap (Contact c, Set<PostalAddressFieldDetails> postal_addresses) {
var map = new Embed ();
var map_factory = MapSourceFactory.dup_default ();
map_grid.add (map);
map_view = map.get_view ();
map_view.set_map_source (map_factory.create (MAP_SOURCE_OSM_MAPQUEST));
map_view.zoom_level = map_view.max_zoom_level - 2;
marker_layer = new MarkerLayer ();
map_view.add_layer (marker_layer);
/* This is a hack to make sure we do not get the FLEUR
* drag cursor on click. Ideally champlain would let us
* turn this of with a property. */
map.get_child ().button_press_event.connect (() => {
map.get_child ().get_window ().set_cursor (null);
return false;
});
/* Do not propagate event to the Champlain clutter stage */
map_view.get_stage ().captured_event.connect (() => { return true; });
map.button_press_event.connect(() => {
activate_action ("org.gnome.Maps",
"show-contact",
new Variant ("s", c.individual.id),
Gtk.get_current_event_time ());
return true;
});
addresses = postal_addresses;
found_places = new GLib.List<Place>();
mutex = Mutex ();
}
public void load () {
map_stack.visible_child = map_icon;
var geocodes = 0;
foreach (var addr in addresses) {
Contact.geocode_address.begin (addr.value, (object, res) => {
mutex.lock ();
var place = Contact.geocode_address.end (res);
geocodes++;
if (place != null)
found_places.prepend (place);
if (geocodes == addresses.size && found_places.length () > 0)
show_map ();
mutex.unlock ();
});
}
}
private void show_pin () {
var theme = IconTheme.get_default ();
var actor = new Clutter.Actor ();
try {
var pixbuf = theme.load_icon ("maps-pin", 0, 0);
var image = new Clutter.Image ();
image.set_data (pixbuf.get_pixels (),
Cogl.PixelFormat.RGBA_8888,
pixbuf.get_width (),
pixbuf.get_height (),
pixbuf.get_rowstride ());
actor.set_content (image);
actor.set_size (pixbuf.get_width (),
pixbuf.get_height ());
} catch (GLib.Error e) {
/* No good things to do here */
}
var marker = new Marker ();
var place = found_places.nth_data (0);
marker.latitude = place.location.latitude;
marker.longitude = place.location.longitude;
marker.add_child (actor);
marker_layer.add_marker (marker);
}
private void show_labels () {
foreach (var place in found_places) {
var label = new Champlain.Label ();
/* Getting street address resolution (house number)
* from OpenStreetMap is quite rare unfortunately */
if (place.street_address != null)
label.text = place.street_address;
else
label.text = place.street;
label.latitude = place.location.latitude;
label.longitude = place.location.longitude;
marker_layer.add_marker(label);
}
}
void on_allocation_changed () {
if (alloc_id == 0)
return;
var markers = (marker_layer as Clutter.Actor).get_children ();
if ((markers.nth_data (0) as Marker).height == 0)
return;
marker_layer.disconnect (alloc_id);
alloc_id = 0;
if (found_places.length () == 1) {
var place = found_places.nth_data (0);
map_view.center_on (place.location.latitude,
place.location.longitude);
} else {
var bbox = new Champlain.BoundingBox ();
/* Make sure that the markers are visible */
foreach (var marker in markers) {
var x = map_view.longitude_to_x ((marker as Marker).longitude);
var y = map_view.latitude_to_y ((marker as Marker).latitude);
/* 256 is the only supported tile size in Champlain */
var lat = map_view.y_to_latitude (y - marker.height * 256);
var lon = map_view.x_to_longitude (x + marker.width * 256);
bbox.extend (lat, lon);
bbox.extend ((marker as Marker).latitude,
(marker as Marker).longitude);
}
map_view.ensure_visible (bbox, false);
}
}
private void show_map () {
if (found_places.length () == 0) {
map_stack.visible_child = map_icon;
return;
}
if (found_places.length () == 1) {
show_pin ();
} else {
show_labels ();
}
map_stack.visible_child = map_grid;
/* We need to make sure that the markers knows about their width
* before we calculate the visible bounding box and show
* the markers.*/
alloc_id = marker_layer.allocation_changed.connect (on_allocation_changed);
}
}
......@@ -267,7 +267,7 @@ public class Contacts.App : Gtk.Application {
public override void activate () {
var icon_theme = IconTheme.get_default ();
icon_theme.append_search_path(Config.PKGDATADIR + "/icons");
icon_theme.append_search_path (Config.PKGDATADIR + "/icons");
/* window creation code */
if (window == null) {
......
......@@ -221,6 +221,13 @@ public class Contacts.ContactSheet : Grid {
}
add_row_with_label (ref i, TypeSet.general.format_type (addr), all_strs);
}
if (addr_details.postal_addresses.size > 0) {
var map = new AddressMap (c, addr_details.postal_addresses);
map.load ();
attach (map, 1, i, 1, 1);
i++;
}
}
if (i != 3)
......
......@@ -20,6 +20,7 @@ using Gtk;
using Folks;
using Gee;
using TelepathyGLib;
using Geocode;
public errordomain ContactError {
NOT_IMPLEMENTED,
......@@ -672,6 +673,39 @@ public class Contacts.Contact : GLib.Object {
return res;
}
public static async Place geocode_address (PostalAddress addr) {
SourceFunc callback = geocode_address.callback;
var params = new HashTable<string, GLib.Value?>(str_hash, str_equal);
if (is_set (addr.street))
params.insert("street", addr.street);
if (is_set (addr.locality))
params.insert("locality", addr.locality);
if (is_set (addr.region))
params.insert("region", addr.region);
if (is_set (addr.country))
params.insert("country", addr.country);
Place? place = null;
var forward = new Forward.for_params (params);
forward.search_async.begin (null, (object, res) => {
try {
var places = forward.search_async.end (res);
place = places.nth_data (0);
callback ();
} catch (GLib.Error e) {
debug ("No geocode result found for contact");
callback ();
}
});
yield;
return place;
}
public static string[] format_address (PostalAddress addr) {
string[] lines = {};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment