Compare commits

...
Sign in to create a new pull request.

10 commits

Author SHA1 Message Date
Jonas Danielsson
9ec57f6dc6 Merge branch 'fixup' into wip/map-widget
src/contacts-app.vala
2014-12-16 07:45:33 -05:00
Jonas Danielsson
2bc3aae06e Add a map to the contacts sheet 2014-12-16 07:44:16 -05:00
Jonas Danielsson
67c38f90fc Add map widget 2014-12-16 07:43:54 -05:00
Jonas Danielsson
697be63f78 contacts-contact: Add method to geocode a contact
https://bugzilla.gnome.org/show_bug.cgi?id=658553
2014-12-16 07:09:00 -05:00
Jonas Danielsson
511df2cf5b contacts-app: Add our search path to icon theme
https://bugzilla.gnome.org/show_bug.cgi?id=658553
2014-12-16 07:09:00 -05:00
Jonas Danielsson
44d68d2cdd Add a map pin icon
https://bugzilla.gnome.org/show_bug.cgi?id=658553
2014-12-16 07:09:00 -05:00
Jonas Danielsson
b00badcc36 contacts-utils: Add activate_action function
Add a function that activates an action on a given appid.

https://bugzilla.gnome.org/show_bug.cgi?id=658553
2014-12-16 07:09:00 -05:00
Jonas Danielsson
b8fb54534e contacts-app: Add our search path to icon theme 2014-12-16 06:02:07 -05:00
Jonas Danielsson
5e37a70082 Add a map pin icon 2014-12-16 06:02:06 -05:00
Jonas Danielsson
3118655955 contacts-utils: Add activate_action function
Add a function that activates an action on a given appid.
2014-12-16 06:02:06 -05:00
12 changed files with 701 additions and 1 deletions

View file

@ -50,10 +50,12 @@ pkg_modules="gtk+-3.0 >= 3.12.0
libedataserver-1.2 >= 3.5.3 libedataserver-1.2 >= 3.5.3
goa-1.0 goa-1.0
gee-0.8 gee-0.8
champlain-gtk-0.12
geocode-glib-1.0
" "
PKG_CHECK_MODULES(CONTACTS, [$pkg_modules]) 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) AC_SUBST(CONTACTS_PACKAGES)
# Optional dependency for the user accounts panel # Optional dependency for the user accounts panel

View file

@ -37,6 +37,7 @@ EXTRA_DIST = \
org.gnome.Contacts.search-provider.ini.in.in \ org.gnome.Contacts.search-provider.ini.in.in \
contacts.gresource.xml \ contacts.gresource.xml \
ui/app-menu.ui \ ui/app-menu.ui \
ui/contacts-address-map.ui \
ui/contacts-window.ui \ ui/contacts-window.ui \
ui/contacts-list-pane.ui \ ui/contacts-list-pane.ui \
ui/style.css \ ui/style.css \
@ -52,3 +53,29 @@ DISTCLEANFILES = \
org.gnome.Contacts.search-provider.ini \ org.gnome.Contacts.search-provider.ini \
gnome-contacts.desktop \ gnome-contacts.desktop \
gnome-contacts.desktop.in gnome-contacts.desktop.in
private_icons = \
hicolor_apps_32x32_maps-pin.svg \
$(NULL)
install-icons:
for icon in $(private_icons); do \
THEME=`echo $$icon | cut -d_ -f1`; \
CONTEXT=`echo $$icon | cut -d_ -f2`; \
SIZE=`echo $$icon | cut -d_ -f3`; \
ICONFILE=`echo $$icon | cut -d_ -f4`; \
mkdir -p $(DESTDIR)$(datadir)/gnome-contacts/icons/$$THEME/$$SIZE/$$CONTEXT; \
$(INSTALL_DATA) $(srcdir)/icons/$$icon $(DESTDIR)$(datadir)/gnome-contacts/icons/$$THEME/$$SIZE/$$CONTEXT/$$ICONFILE; \
done
uninstall-icons:
-for icon in $(private_icons); do \
THEME=`echo $$icon | cut -d_ -f1`; \
CONTEXT=`echo $$icon | cut -d_ -f2`; \
SIZE=`echo $$icon | cut -d_ -f3`; \
ICONFILE=`echo $$icon | cut -d_ -f4`; \
rm -f $(DESTDIR)$(datadir)/gnome-contacts/icons/$$THEME/$$SIZE/$$CONTEXT/$$ICONFILE; \
done
install-data-local: install-icons

View file

@ -3,6 +3,7 @@
<gresource prefix="/org/gnome/contacts"> <gresource prefix="/org/gnome/contacts">
<file compressed="true">ui/style.css</file> <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/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-window.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/contacts-list-pane.ui</file> <file compressed="true" preprocess="xml-stripblanks">ui/contacts-list-pane.ui</file>
</gresource> </gresource>

View file

@ -0,0 +1,336 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32px"
height="32px"
id="svg6019"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="New document 2">
<defs
id="defs6021">
<linearGradient
inkscape:collect="always"
id="linearGradient6936">
<stop
style="stop-color:#888a85;stop-opacity:1;"
offset="0"
id="stop6938" />
<stop
style="stop-color:#d4d4d2;stop-opacity:1"
offset="1"
id="stop6940" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient6924">
<stop
style="stop-color:#ffffff;stop-opacity:0"
offset="0"
id="stop6926" />
<stop
id="stop6932"
offset="0.45113504"
style="stop-color:#ffffff;stop-opacity:0.54509804;" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop6928" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient6914">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop6916" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop6918" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient6869">
<stop
style="stop-color:#4d0000;stop-opacity:1"
offset="0"
id="stop6871" />
<stop
style="stop-color:#540000;stop-opacity:1"
offset="1"
id="stop6873" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient6859">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop6861" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop6863" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient6841">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop6843" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop6845" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient6031">
<stop
style="stop-color:#ff5757;stop-opacity:1"
offset="0"
id="stop6033" />
<stop
style="stop-color:#c90000;stop-opacity:1"
offset="1"
id="stop6035" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient6031"
id="radialGradient6037"
cx="14.702265"
cy="10.82002"
fx="14.702265"
fy="10.82002"
r="11.097416"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0827713,0,8.6406e-7,1,-1.2169342,1.7279646e-8)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient6031-3"
id="radialGradient6037-8"
cx="14.702265"
cy="10.82002"
fx="14.702265"
fy="10.82002"
r="11.097416"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0827713,0,8.6406e-7,1,-1.2169342,1.7279646e-8)" />
<linearGradient
inkscape:collect="always"
id="linearGradient6031-3">
<stop
style="stop-color:#ff5757;stop-opacity:1"
offset="0"
id="stop6033-4" />
<stop
style="stop-color:#c90000;stop-opacity:1"
offset="1"
id="stop6035-0" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6841"
id="linearGradient6847"
x1="16.789011"
y1="4.3640823"
x2="16.789011"
y2="21.97056"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6859"
id="linearGradient6865"
x1="16.751778"
y1="7.2421875"
x2="16.751778"
y2="10.1875"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6869"
id="linearGradient6875"
x1="17.66885"
y1="5.3010869"
x2="17.66885"
y2="22.728249"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6859-2"
id="linearGradient6865-2"
x1="16.751778"
y1="7.2421875"
x2="16.751778"
y2="10.1875"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
id="linearGradient6859-2">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop6861-0" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop6863-1" />
</linearGradient>
<linearGradient
y2="10.1875"
x2="16.751778"
y1="7.2421875"
x1="16.751778"
gradientUnits="userSpaceOnUse"
id="linearGradient6892"
xlink:href="#linearGradient6859-2"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6914"
id="linearGradient6920"
x1="15.865708"
y1="17.835768"
x2="15.865708"
y2="21"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6924"
id="linearGradient6930"
x1="15.59375"
y1="23.203125"
x2="15.59375"
y2="26"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6936"
id="linearGradient6942"
x1="15.616699"
y1="21.594204"
x2="15.616699"
y2="27.06004"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,0.019699)" />
<filter
inkscape:collect="always"
id="filter6962"
x="-0.18475209"
width="1.3695042"
y="-0.31176915"
height="1.6235383">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.32475953"
id="feGaussianBlur6964" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.6568542"
inkscape:cx="20.343696"
inkscape:cy="3.7141481"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:snap-bbox="true"
inkscape:snap-nodes="false"
inkscape:window-width="1600"
inkscape:window-height="841"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid6027" />
</sodipodi:namedview>
<metadata
id="metadata6024">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
sodipodi:type="arc"
style="opacity:0.3;fill:#000000;fill-opacity:1;stroke:none;filter:url(#filter6962)"
id="path6944"
sodipodi:cx="15.265625"
sodipodi:cy="28.78125"
sodipodi:rx="2.109375"
sodipodi:ry="1.25"
d="m 17.375,28.78125 a 2.109375,1.25 0 1 1 -4.21875,0 2.109375,1.25 0 1 1 4.21875,0 z"
transform="matrix(1.2010763,0,0,1.3735147,-2.8351801,-10.281469)" />
<path
style="fill:url(#linearGradient6942);fill-opacity:1;stroke:#2e3436;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
d="m 14.5,18.519699 2,0 0,9.995926 c 0,0 -0.001,0.984375 -0.984375,0.984375 C 14.532257,29.5 14.5,28.515625 14.5,28.515625 z"
id="rect6867"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccczcc" />
<rect
style="fill:url(#linearGradient6920);fill-opacity:1;stroke:none"
id="rect6912"
width="2.990447"
height="5"
x="14.009553"
y="17" />
<path
sodipodi:type="arc"
style="fill:url(#radialGradient6037);fill-opacity:1;stroke:url(#linearGradient6875);stroke-width:1.48626076999999990;stroke-opacity:1"
id="path6029"
sodipodi:cx="16.789009"
sodipodi:cy="15.568204"
sodipodi:rx="10.403828"
sodipodi:ry="10.403828"
d="m 27.192837,15.568204 a 10.403828,10.403828 0 1 1 -20.8076556,0 10.403828,10.403828 0 1 1 20.8076556,0 z"
transform="matrix(0.67282935,0,0,0.67282935,4.2038612,1.0252547)" />
<path
sodipodi:type="arc"
style="opacity:0.25203253;fill:none;stroke:url(#linearGradient6847);stroke-width:1.71491659;stroke-opacity:1"
id="path6029-6"
sodipodi:cx="16.789009"
sodipodi:cy="15.568204"
sodipodi:rx="10.403828"
sodipodi:ry="10.403828"
d="m 27.192837,15.568204 a 10.403828,10.403828 0 1 1 -20.8076556,0 10.403828,10.403828 0 1 1 20.8076556,0 z"
transform="matrix(0.58311869,0,0,-0.58311869,5.7100144,20.57811)" />
<path
sodipodi:type="arc"
style="opacity:0.62601624;fill:url(#linearGradient6865);fill-opacity:1;stroke:none"
id="path6849"
sodipodi:cx="16.665859"
sodipodi:cy="8.828125"
sodipodi:rx="3.6658583"
sodipodi:ry="2.265625"
d="m 20.331717,8.828125 a 3.6658583,2.265625 0 1 1 -7.331716,0 3.6658583,2.265625 0 1 1 7.331716,0 z"
transform="matrix(0.95475594,0,0,1.1034483,-0.41182811,-1.2413798)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,37 @@
<?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>

View file

@ -10,6 +10,11 @@ ContactsListPane.frame:dir(rtl) {
border-width: 0 0 0 1px; border-width: 0 0 0 1px;
} }
.contacts-map {
background-color: @theme_bg_color;
color: gray;
}
/* contatcs view new color */ /* contatcs view new color */
.contacts-view { .contacts-view {
background-color: transparent; background-color: transparent;

View file

@ -25,6 +25,7 @@ bin_PROGRAMS = gnome-contacts
vala_sources = \ vala_sources = \
contacts-app.vala \ contacts-app.vala \
contacts-address-map.vala \
contacts-contact.vala \ contacts-contact.vala \
contacts-contact-sheet.vala \ contacts-contact-sheet.vala \
contacts-contact-editor.vala \ contacts-contact-editor.vala \

View file

@ -0,0 +1,206 @@
/* -*- 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);
}
}

View file

@ -266,6 +266,9 @@ public class Contacts.App : Gtk.Application {
} }
public override void activate () { public override void activate () {
var icon_theme = IconTheme.get_default ();
icon_theme.append_search_path (Config.PKGDATADIR + "/icons");
/* window creation code */ /* window creation code */
if (window == null) { if (window == null) {
if (!contacts_store.is_prepared) { if (!contacts_store.is_prepared) {

View file

@ -221,6 +221,13 @@ public class Contacts.ContactSheet : Grid {
} }
add_row_with_label (ref i, TypeSet.general.format_type (addr), all_strs); 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) if (i != 3)

View file

@ -20,6 +20,7 @@ using Gtk;
using Folks; using Folks;
using Gee; using Gee;
using TelepathyGLib; using TelepathyGLib;
using Geocode;
public errordomain ContactError { public errordomain ContactError {
NOT_IMPLEMENTED, NOT_IMPLEMENTED,
@ -672,6 +673,39 @@ public class Contacts.Contact : GLib.Object {
return res; 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) { public static string[] format_address (PostalAddress addr) {
string[] lines = {}; string[] lines = {};

View file

@ -20,6 +20,9 @@ using Gtk;
using Folks; using Folks;
using Gee; using Gee;
using TelepathyGLib; using TelepathyGLib;
using DBus;
using GLib;
using Gdk;
namespace Contacts { namespace Contacts {
private static bool is_set (string? str) { private static bool is_set (string? str) {
@ -51,6 +54,44 @@ namespace Contacts {
ListBoxRow? before_row) { ListBoxRow? before_row) {
row.set_header (new Separator (Orientation.HORIZONTAL)); row.set_header (new Separator (Orientation.HORIZONTAL));
} }
[DBus (name = "org.freedesktop.Application")]
interface FreedesktopApplication : Object {
[DBus (name = "ActivateAction")]
public abstract void ActivateAction (string action,
Variant[] parameter,
HashTable<string, Variant> data) throws IOError;
}
public void activate_action (string app_id,
string action,
Variant? parameter,
uint32 timestamp) {
FreedesktopApplication? con = null;
try {
string object_path = "/" + app_id.replace(".", "/");
Display display = Display.get_default ();
DesktopAppInfo info = new DesktopAppInfo (app_id + ".desktop");
Gdk.AppLaunchContext context = display.get_app_launch_context ();
con = Bus.get_proxy_sync (BusType.SESSION, app_id, object_path);
context.set_timestamp (timestamp);
Variant[] param_array = {};
if (parameter != null) {
param_array += parameter;
}
var startup_id = context.get_startup_notify_id (info,
new GLib.List<File>());
var data = new HashTable<string, Variant>(str_hash, str_equal);
data.insert ("desktop-startup-id", new Variant.string (startup_id));
con.ActivateAction (action, param_array, data);
} catch (IOError e) {
debug ("Failed to activate action" + action);
}
}
} }
public class Center : Bin { public class Center : Bin {