Contact map cleanups.
This commit is contained in:
@@ -18,28 +18,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
/* This defines WITH_CONTACT_MAPS. */
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CONTACT_MAPS
|
||||
|
||||
#include "e-contact-map.h"
|
||||
#include "e-contact-map-window.h"
|
||||
#include "e-contact-marker.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include <champlain/champlain.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib-object.h>
|
||||
#include "e-contact-map.h"
|
||||
#include "e-contact-marker.h"
|
||||
|
||||
#define E_CONTACT_MAP_WINDOW_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE \
|
||||
((obj), E_TYPE_CONTACT_MAP_WINDOW, EContactMapWindowPrivate))
|
||||
|
||||
G_DEFINE_TYPE (EContactMapWindow, e_contact_map_window, GTK_TYPE_WINDOW)
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE \
|
||||
((obj), E_TYPE_CONTACT_MAP_WINDOW, EContactMapWindowPrivate))
|
||||
|
||||
struct _EContactMapWindowPrivate {
|
||||
EContactMap *map;
|
||||
@@ -50,7 +46,8 @@ struct _EContactMapWindowPrivate {
|
||||
GtkWidget *search_entry;
|
||||
GtkListStore *completion_model;
|
||||
|
||||
GHashTable *hash_table; /* Hash table contact-name -> marker */
|
||||
/* contact name -> marker */
|
||||
GHashTable *hash_table;
|
||||
|
||||
GtkWidget *spinner;
|
||||
gint tasks_cnt;
|
||||
@@ -61,7 +58,12 @@ enum {
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static gint signals[LAST_SIGNAL] = {0};
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
G_DEFINE_TYPE (
|
||||
EContactMapWindow,
|
||||
e_contact_map_window,
|
||||
GTK_TYPE_WINDOW)
|
||||
|
||||
static void
|
||||
marker_doubleclick_cb (ClutterActor *actor,
|
||||
@@ -78,37 +80,39 @@ marker_doubleclick_cb (ClutterActor *actor,
|
||||
}
|
||||
|
||||
static void
|
||||
book_contacts_received_cb (GObject *source_object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
contact_map_window_get_contacts_cb (GObject *source_object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
EContactMapWindow *window = user_data;
|
||||
EBookClient *client = E_BOOK_CLIENT (source_object);
|
||||
GSList *contacts = NULL, *p;
|
||||
GError *error = NULL;
|
||||
EContactMapWindow *window;
|
||||
GSList *list = NULL, *link;
|
||||
GError *local_error = NULL;
|
||||
|
||||
e_book_client_get_contacts_finish (client, result, &contacts, &error);
|
||||
window = E_CONTACT_MAP_WINDOW (user_data);
|
||||
|
||||
if (error != NULL) {
|
||||
e_book_client_get_contacts_finish (
|
||||
E_BOOK_CLIENT (source_object),
|
||||
result, &list, &local_error);
|
||||
|
||||
if (local_error != NULL) {
|
||||
g_warning (
|
||||
"%s: Failed to get contacts: %s",
|
||||
G_STRFUNC, error->message);
|
||||
g_error_free (error);
|
||||
G_STRFUNC, local_error->message);
|
||||
g_error_free (local_error);
|
||||
}
|
||||
|
||||
for (p = contacts; p; p = p->next)
|
||||
e_contact_map_add_contact (
|
||||
window->priv->map, (EContact *) p->data);
|
||||
for (link = list; link != NULL; link = g_slist_next (link)) {
|
||||
EContact *contact = E_CONTACT (link->data);
|
||||
e_contact_map_add_contact (window->priv->map, contact);
|
||||
}
|
||||
|
||||
g_slist_free_full (contacts, (GDestroyNotify) g_object_unref);
|
||||
g_object_unref (client);
|
||||
g_slist_free_full (list, (GDestroyNotify) g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
contact_map_window_zoom_in_cb (GtkButton *button,
|
||||
gpointer user_data)
|
||||
EContactMapWindow *window)
|
||||
{
|
||||
EContactMapWindow *window = user_data;
|
||||
ChamplainView *view;
|
||||
|
||||
view = e_contact_map_get_view (window->priv->map);
|
||||
@@ -118,22 +122,23 @@ contact_map_window_zoom_in_cb (GtkButton *button,
|
||||
|
||||
static void
|
||||
contact_map_window_zoom_out_cb (GtkButton *button,
|
||||
gpointer user_data)
|
||||
EContactMapWindow *window)
|
||||
{
|
||||
EContactMapWindow *window = user_data;
|
||||
ChamplainView *view;
|
||||
|
||||
view = e_contact_map_get_view (window->priv->map);
|
||||
|
||||
champlain_view_zoom_out (view);
|
||||
}
|
||||
|
||||
static void
|
||||
zoom_level_changed_cb (ChamplainView *view,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
contact_map_window_zoom_level_changed_cb (ChamplainView *view,
|
||||
GParamSpec *pspec,
|
||||
EContactMapWindow *window)
|
||||
{
|
||||
EContactMapWindow *window = user_data;
|
||||
gint zoom_level = champlain_view_get_zoom_level (view);
|
||||
gint zoom_level;
|
||||
|
||||
zoom_level = champlain_view_get_zoom_level (view);
|
||||
|
||||
gtk_widget_set_sensitive (
|
||||
window->priv->zoom_in_btn,
|
||||
@@ -149,86 +154,90 @@ zoom_level_changed_cb (ChamplainView *view,
|
||||
* that the contact has really been added to map.
|
||||
*/
|
||||
static void
|
||||
map_contact_added_cb (EContactMap *map,
|
||||
ClutterActor *marker,
|
||||
gpointer user_data)
|
||||
contact_map_window_contact_added_cb (EContactMap *map,
|
||||
ClutterActor *marker,
|
||||
EContactMapWindow *window)
|
||||
{
|
||||
EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
|
||||
const gchar *name;
|
||||
GtkListStore *list_store;
|
||||
GtkTreeIter iter;
|
||||
const gchar *name;
|
||||
|
||||
name = champlain_label_get_text (CHAMPLAIN_LABEL (marker));
|
||||
|
||||
g_hash_table_insert (
|
||||
priv->hash_table,
|
||||
window->priv->hash_table,
|
||||
g_strdup (name), marker);
|
||||
|
||||
gtk_list_store_append (priv->completion_model, &iter);
|
||||
gtk_list_store_set (
|
||||
priv->completion_model, &iter,
|
||||
0, name, -1);
|
||||
list_store = window->priv->completion_model;
|
||||
gtk_list_store_append (list_store, &iter);
|
||||
gtk_list_store_set (list_store, &iter, 0, name, -1);
|
||||
|
||||
g_signal_connect (
|
||||
marker, "double-clicked",
|
||||
G_CALLBACK (marker_doubleclick_cb), user_data);
|
||||
G_CALLBACK (marker_doubleclick_cb), window);
|
||||
|
||||
priv->tasks_cnt--;
|
||||
if (priv->tasks_cnt == 0) {
|
||||
gtk_spinner_stop (GTK_SPINNER (priv->spinner));
|
||||
gtk_widget_hide (priv->spinner);
|
||||
window->priv->tasks_cnt--;
|
||||
if (window->priv->tasks_cnt == 0) {
|
||||
gtk_spinner_stop (GTK_SPINNER (window->priv->spinner));
|
||||
gtk_widget_hide (window->priv->spinner);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
map_contact_removed_cb (EContactMap *map,
|
||||
const gchar *name,
|
||||
gpointer user_data)
|
||||
contact_map_window_contact_removed_cb (EContactMap *map,
|
||||
const gchar *name,
|
||||
EContactMapWindow *window)
|
||||
{
|
||||
EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
|
||||
GtkListStore *list_store;
|
||||
GtkTreeModel *tree_model;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model = GTK_TREE_MODEL (priv->completion_model);
|
||||
gboolean iter_valid;
|
||||
|
||||
g_hash_table_remove (priv->hash_table, name);
|
||||
list_store = window->priv->completion_model;
|
||||
tree_model = GTK_TREE_MODEL (list_store);
|
||||
|
||||
if (gtk_tree_model_get_iter_first (model, &iter)) {
|
||||
do {
|
||||
gchar *name_str;
|
||||
gtk_tree_model_get (model, &iter, 0, &name_str, -1);
|
||||
if (g_ascii_strcasecmp (name_str, name) == 0) {
|
||||
g_free (name_str);
|
||||
gtk_list_store_remove (priv->completion_model, &iter);
|
||||
break;
|
||||
}
|
||||
g_free (name_str);
|
||||
} while (gtk_tree_model_iter_next (model, &iter));
|
||||
g_hash_table_remove (window->priv->hash_table, name);
|
||||
|
||||
iter_valid = gtk_tree_model_get_iter_first (tree_model, &iter);
|
||||
|
||||
while (iter_valid) {
|
||||
gchar *name_str;
|
||||
gboolean match;
|
||||
|
||||
gtk_tree_model_get (tree_model, &iter, 0, &name_str, -1);
|
||||
match = (g_ascii_strcasecmp (name_str, name) == 0);
|
||||
g_free (name_str);
|
||||
|
||||
if (match) {
|
||||
gtk_list_store_remove (list_store, &iter);
|
||||
break;
|
||||
}
|
||||
|
||||
iter_valid = gtk_tree_model_iter_next (tree_model, &iter);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
map_contact_geocoding_started_cb (EContactMap *map,
|
||||
ClutterActor *marker,
|
||||
gpointer user_data)
|
||||
contact_map_window_geocoding_started_cb (EContactMap *map,
|
||||
ClutterActor *marker,
|
||||
EContactMapWindow *window)
|
||||
{
|
||||
EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
|
||||
gtk_spinner_start (GTK_SPINNER (window->priv->spinner));
|
||||
gtk_widget_show (window->priv->spinner);
|
||||
|
||||
gtk_spinner_start (GTK_SPINNER (priv->spinner));
|
||||
gtk_widget_show (priv->spinner);
|
||||
|
||||
priv->tasks_cnt++;
|
||||
window->priv->tasks_cnt++;
|
||||
}
|
||||
|
||||
static void
|
||||
map_contact_geocoding_failed_cb (EContactMap *map,
|
||||
const gchar *name,
|
||||
gpointer user_data)
|
||||
contact_map_window_geocoding_failed_cb (EContactMap *map,
|
||||
const gchar *name,
|
||||
EContactMapWindow *window)
|
||||
{
|
||||
EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
|
||||
window->priv->tasks_cnt--;
|
||||
|
||||
priv->tasks_cnt--;
|
||||
|
||||
if (priv->tasks_cnt == 0) {
|
||||
gtk_spinner_stop (GTK_SPINNER (priv->spinner));
|
||||
gtk_widget_hide (priv->spinner);
|
||||
if (window->priv->tasks_cnt == 0) {
|
||||
gtk_spinner_stop (GTK_SPINNER (window->priv->spinner));
|
||||
gtk_widget_hide (window->priv->spinner);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,42 +288,37 @@ entry_completion_match_selected_cb (GtkEntryCompletion *widget,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
contact_map_window_finalize (GObject *object)
|
||||
{
|
||||
EContactMapWindowPrivate *priv;
|
||||
|
||||
priv = E_CONTACT_MAP_WINDOW (object)->priv;
|
||||
|
||||
if (priv->hash_table) {
|
||||
g_hash_table_destroy (priv->hash_table);
|
||||
priv->hash_table = NULL;
|
||||
}
|
||||
|
||||
/* Chain up to parent's finalize() method. */
|
||||
G_OBJECT_CLASS (e_contact_map_window_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
contact_map_window_dispose (GObject *object)
|
||||
{
|
||||
EContactMapWindowPrivate *priv;
|
||||
|
||||
priv = E_CONTACT_MAP_WINDOW (object)->priv;
|
||||
priv = E_CONTACT_MAP_WINDOW_GET_PRIVATE (object);
|
||||
|
||||
if (priv->map) {
|
||||
if (priv->map != NULL) {
|
||||
gtk_widget_destroy (GTK_WIDGET (priv->map));
|
||||
priv->map = NULL;
|
||||
}
|
||||
|
||||
if (priv->completion_model) {
|
||||
g_object_unref (priv->completion_model);
|
||||
priv->completion_model = NULL;
|
||||
}
|
||||
g_clear_object (&priv->completion_model);
|
||||
|
||||
/* Chain up to parent's dispose() method. */
|
||||
G_OBJECT_CLASS (e_contact_map_window_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
contact_map_window_finalize (GObject *object)
|
||||
{
|
||||
EContactMapWindowPrivate *priv;
|
||||
|
||||
priv = E_CONTACT_MAP_WINDOW_GET_PRIVATE (object);
|
||||
|
||||
g_hash_table_destroy (priv->hash_table);
|
||||
|
||||
/* Chain up to parent's finalize() method. */
|
||||
G_OBJECT_CLASS (e_contact_map_window_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
e_contact_map_window_class_init (EContactMapWindowClass *class)
|
||||
{
|
||||
@@ -323,8 +327,8 @@ e_contact_map_window_class_init (EContactMapWindowClass *class)
|
||||
g_type_class_add_private (class, sizeof (EContactMapWindowPrivate));
|
||||
|
||||
object_class = G_OBJECT_CLASS (class);
|
||||
object_class->finalize = contact_map_window_finalize;
|
||||
object_class->dispose = contact_map_window_dispose;
|
||||
object_class->finalize = contact_map_window_finalize;
|
||||
|
||||
signals[SHOW_CONTACT_EDITOR] = g_signal_new (
|
||||
"show-contact-editor",
|
||||
@@ -371,19 +375,19 @@ e_contact_map_window_init (EContactMapWindow *window)
|
||||
priv->map = E_CONTACT_MAP (map);
|
||||
g_signal_connect (
|
||||
view, "notify::zoom-level",
|
||||
G_CALLBACK (zoom_level_changed_cb), window);
|
||||
G_CALLBACK (contact_map_window_zoom_level_changed_cb), window);
|
||||
g_signal_connect (
|
||||
map, "contact-added",
|
||||
G_CALLBACK (map_contact_added_cb), window);
|
||||
G_CALLBACK (contact_map_window_contact_added_cb), window);
|
||||
g_signal_connect (
|
||||
map, "contact-removed",
|
||||
G_CALLBACK (map_contact_removed_cb), window);
|
||||
G_CALLBACK (contact_map_window_contact_removed_cb), window);
|
||||
g_signal_connect (
|
||||
map, "geocoding-started",
|
||||
G_CALLBACK (map_contact_geocoding_started_cb), window);
|
||||
G_CALLBACK (contact_map_window_geocoding_started_cb), window);
|
||||
g_signal_connect (
|
||||
map, "geocoding-failed",
|
||||
G_CALLBACK (map_contact_geocoding_failed_cb), window);
|
||||
G_CALLBACK (contact_map_window_geocoding_failed_cb), window);
|
||||
|
||||
/* HBox container */
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 7);
|
||||
@@ -455,8 +459,15 @@ e_contact_map_window_init (EContactMapWindow *window)
|
||||
EContactMapWindow *
|
||||
e_contact_map_window_new (void)
|
||||
{
|
||||
return g_object_new (
|
||||
E_TYPE_CONTACT_MAP_WINDOW, NULL);
|
||||
return g_object_new (E_TYPE_CONTACT_MAP_WINDOW, NULL);
|
||||
}
|
||||
|
||||
EContactMap *
|
||||
e_contact_map_window_get_map (EContactMapWindow *window)
|
||||
{
|
||||
g_return_val_if_fail (E_IS_CONTACT_MAP_WINDOW (window), NULL);
|
||||
|
||||
return window->priv->map;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -473,27 +484,15 @@ e_contact_map_window_load_addressbook (EContactMapWindow *map,
|
||||
g_return_if_fail (E_IS_CONTACT_MAP_WINDOW (map));
|
||||
g_return_if_fail (E_IS_BOOK_CLIENT (book_client));
|
||||
|
||||
/* Reference book, so that it does not get deleted before the callback is
|
||||
* involved. The book is unrefed in the callback */
|
||||
g_object_ref (book_client);
|
||||
|
||||
book_query = e_book_query_field_exists (E_CONTACT_ADDRESS);
|
||||
query_string = e_book_query_to_string (book_query);
|
||||
e_book_query_unref (book_query);
|
||||
|
||||
e_book_client_get_contacts (
|
||||
book_client, query_string, NULL,
|
||||
book_contacts_received_cb, map);
|
||||
contact_map_window_get_contacts_cb, map);
|
||||
|
||||
g_free (query_string);
|
||||
}
|
||||
|
||||
EContactMap *
|
||||
e_contact_map_window_get_map (EContactMapWindow *window)
|
||||
{
|
||||
g_return_val_if_fail (E_IS_CONTACT_MAP_WINDOW (window), NULL);
|
||||
|
||||
return window->priv->map;
|
||||
}
|
||||
|
||||
#endif /* WITH_CONTACT_MAPS */
|
||||
|
||||
@@ -62,17 +62,17 @@ struct _EContactMapWindow {
|
||||
struct _EContactMapWindowClass {
|
||||
GtkWindowClass parent_class;
|
||||
|
||||
void (*show_contact_editor) (EContactMapWindow *window,
|
||||
const gchar *contact_uid);
|
||||
void (*show_contact_editor) (EContactMapWindow *window,
|
||||
const gchar *contact_uid);
|
||||
};
|
||||
|
||||
GType e_contact_map_window_get_type (void) G_GNUC_CONST;
|
||||
EContactMapWindow * e_contact_map_window_new (void);
|
||||
|
||||
void e_contact_map_window_load_addressbook (EContactMapWindow *window,
|
||||
EBookClient *book);
|
||||
|
||||
EContactMap * e_contact_map_window_get_map (EContactMapWindow *window);
|
||||
GType e_contact_map_window_get_type (void) G_GNUC_CONST;
|
||||
EContactMapWindow *
|
||||
e_contact_map_window_new (void);
|
||||
EContactMap * e_contact_map_window_get_map (EContactMapWindow *window);
|
||||
void e_contact_map_window_load_addressbook
|
||||
(EContactMapWindow *window,
|
||||
EBookClient *book);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -73,33 +73,30 @@ G_DEFINE_TYPE (EContactMap, e_contact_map, GTK_CHAMPLAIN_TYPE_EMBED)
|
||||
static void
|
||||
async_context_free (AsyncContext *async_context)
|
||||
{
|
||||
if (async_context->map != NULL)
|
||||
g_object_unref (async_context->map);
|
||||
g_clear_object (&async_context->map);
|
||||
|
||||
g_slice_free (AsyncContext, async_context);
|
||||
}
|
||||
|
||||
static void
|
||||
contact_map_address_resolved_cb (GObject *source,
|
||||
contact_map_address_resolved_cb (GObject *source_object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GHashTable *resolved = NULL;
|
||||
gpointer marker_ptr;
|
||||
const gchar *name;
|
||||
AsyncContext *async_context = user_data;
|
||||
ChamplainMarkerLayer *marker_layer;
|
||||
ChamplainMarker *marker;
|
||||
GeocodePlace *place;
|
||||
GeocodeLocation *location;
|
||||
GList *search_results;
|
||||
|
||||
g_return_if_fail (async_context != NULL);
|
||||
g_return_if_fail (E_IS_CONTACT_MAP (async_context->map));
|
||||
g_return_if_fail (E_IS_CONTACT_MARKER (async_context->marker));
|
||||
const gchar *name;
|
||||
GError *local_error = NULL;
|
||||
|
||||
marker = CHAMPLAIN_MARKER (async_context->marker);
|
||||
marker_layer = async_context->map->priv->marker_layer;
|
||||
name = champlain_label_get_text (CHAMPLAIN_LABEL (marker));
|
||||
|
||||
/* If the marker_layer does not exist anymore, the map has
|
||||
* probably been destroyed before this callback was launched.
|
||||
@@ -110,10 +107,24 @@ contact_map_address_resolved_cb (GObject *source,
|
||||
goto exit;
|
||||
|
||||
search_results = geocode_forward_search_finish (
|
||||
GEOCODE_FORWARD (source), result, NULL);
|
||||
GEOCODE_FORWARD (source_object), result, &local_error);
|
||||
|
||||
/* Sanity check. */
|
||||
g_warn_if_fail (
|
||||
((search_results != NULL) && (local_error == NULL)) ||
|
||||
((search_results == NULL) && (local_error != NULL)));
|
||||
|
||||
/* Keep quiet if the search just came up empty. */
|
||||
if (g_error_matches (local_error, GEOCODE_ERROR, GEOCODE_ERROR_NO_MATCHES)) {
|
||||
g_clear_error (&local_error);
|
||||
|
||||
/* Leave a breadcrumb on the console for any other errors. */
|
||||
} else if (local_error != NULL) {
|
||||
g_warning ("%s: %s", G_STRFUNC, local_error->message);
|
||||
g_clear_error (&local_error);
|
||||
}
|
||||
|
||||
if (search_results == NULL) {
|
||||
name = champlain_label_get_text (CHAMPLAIN_LABEL (marker));
|
||||
g_signal_emit (
|
||||
async_context->map,
|
||||
signals[GEOCODING_FAILED], 0, name);
|
||||
@@ -135,7 +146,6 @@ contact_map_address_resolved_cb (GObject *source,
|
||||
g_list_free (search_results);
|
||||
|
||||
/* Store the marker in the hash table, using its label as key. */
|
||||
name = champlain_label_get_text (CHAMPLAIN_LABEL (marker));
|
||||
marker_ptr = g_hash_table_lookup (
|
||||
async_context->map->priv->markers, name);
|
||||
if (marker_ptr != NULL) {
|
||||
@@ -192,47 +202,14 @@ address_to_xep (EContactAddress *address)
|
||||
return hash_table;
|
||||
}
|
||||
|
||||
static void
|
||||
resolve_marker_position (EContactMap *map,
|
||||
EContactMarker *marker,
|
||||
EContactAddress *address)
|
||||
{
|
||||
GeocodeForward *geocoder;
|
||||
AsyncContext *async_context;
|
||||
GHashTable *hash_table;
|
||||
|
||||
g_return_if_fail (E_IS_CONTACT_MAP (map));
|
||||
g_return_if_fail (address != NULL);
|
||||
|
||||
hash_table = address_to_xep (address);
|
||||
geocoder = geocode_forward_new_for_params (hash_table);
|
||||
g_hash_table_destroy (hash_table);
|
||||
|
||||
async_context = g_slice_new0 (AsyncContext);
|
||||
async_context->map = g_object_ref (map);
|
||||
async_context->marker = marker;
|
||||
|
||||
geocode_forward_search_async (
|
||||
geocoder, NULL,
|
||||
contact_map_address_resolved_cb,
|
||||
async_context);
|
||||
|
||||
g_object_unref (geocoder);
|
||||
|
||||
g_signal_emit (map, signals[GEOCODING_STARTED], 0, marker);
|
||||
}
|
||||
|
||||
static void
|
||||
contact_map_finalize (GObject *object)
|
||||
{
|
||||
EContactMapPrivate *priv;
|
||||
|
||||
priv = E_CONTACT_MAP (object)->priv;
|
||||
priv = E_CONTACT_MAP_GET_PRIVATE (object);
|
||||
|
||||
if (priv->markers) {
|
||||
g_hash_table_destroy (priv->markers);
|
||||
priv->markers = NULL;
|
||||
}
|
||||
g_hash_table_destroy (priv->markers);
|
||||
|
||||
/* Chain up to parent's finalize() method. */
|
||||
G_OBJECT_CLASS (e_contact_map_parent_class)->finalize (object);
|
||||
@@ -288,17 +265,16 @@ e_contact_map_class_init (EContactMapClass *class)
|
||||
static void
|
||||
e_contact_map_init (EContactMap *map)
|
||||
{
|
||||
GHashTable *hash_table;
|
||||
ChamplainMarkerLayer *layer;
|
||||
ChamplainView *view;
|
||||
|
||||
map->priv = E_CONTACT_MAP_GET_PRIVATE (map);
|
||||
|
||||
hash_table = g_hash_table_new_full (
|
||||
g_str_hash, g_str_equal,
|
||||
(GDestroyNotify) g_free, NULL);
|
||||
|
||||
map->priv->markers = hash_table;
|
||||
map->priv->markers = g_hash_table_new_full (
|
||||
(GHashFunc) g_str_hash,
|
||||
(GEqualFunc) g_str_equal,
|
||||
(GDestroyNotify) g_free,
|
||||
(GDestroyNotify) NULL);
|
||||
|
||||
view = gtk_champlain_embed_get_view (GTK_CHAMPLAIN_EMBED (map));
|
||||
/* This feature is somehow broken sometimes, so disable it for now */
|
||||
@@ -311,8 +287,7 @@ e_contact_map_init (EContactMap *map)
|
||||
GtkWidget *
|
||||
e_contact_map_new (void)
|
||||
{
|
||||
return g_object_new (
|
||||
E_TYPE_CONTACT_MAP,NULL);
|
||||
return g_object_new (E_TYPE_CONTACT_MAP, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -321,32 +296,43 @@ e_contact_map_add_contact (EContactMap *map,
|
||||
{
|
||||
EContactAddress *address;
|
||||
EContactPhoto *photo;
|
||||
const gchar *contact_name;
|
||||
const gchar *contact_uid;
|
||||
gchar *name;
|
||||
|
||||
g_return_if_fail (map && E_IS_CONTACT_MAP (map));
|
||||
g_return_if_fail (contact && E_IS_CONTACT (contact));
|
||||
g_return_if_fail (E_IS_CONTACT_MAP (map));
|
||||
g_return_if_fail (E_IS_CONTACT (contact));
|
||||
|
||||
photo = e_contact_get (contact, E_CONTACT_PHOTO);
|
||||
contact_name = e_contact_get_const (contact, E_CONTACT_FILE_AS);
|
||||
contact_uid = e_contact_get_const (contact, E_CONTACT_UID);
|
||||
|
||||
address = e_contact_get (contact, E_CONTACT_ADDRESS_HOME);
|
||||
if (address) {
|
||||
name = g_strconcat (e_contact_get_const (contact, E_CONTACT_FILE_AS), " (", _("Home"), ")", NULL);
|
||||
e_contact_map_add_marker (map, name, contact_uid, address, photo);
|
||||
if (address != NULL) {
|
||||
gchar *name;
|
||||
|
||||
name = g_strdup_printf (
|
||||
"%s (%s)", contact_name, _("Home"));
|
||||
e_contact_map_add_marker (
|
||||
map, name, contact_uid, address, photo);
|
||||
g_free (name);
|
||||
|
||||
e_contact_address_free (address);
|
||||
}
|
||||
|
||||
address = e_contact_get (contact, E_CONTACT_ADDRESS_WORK);
|
||||
if (address) {
|
||||
name = g_strconcat (e_contact_get_const (contact, E_CONTACT_FILE_AS), " (", _("Work"), ")", NULL);
|
||||
e_contact_map_add_marker (map, name, contact_uid, address, photo);
|
||||
if (address != NULL) {
|
||||
gchar *name;
|
||||
|
||||
name = g_strdup_printf (
|
||||
"%s (%s)", contact_name, _("Work"));
|
||||
e_contact_map_add_marker (
|
||||
map, name, contact_uid, address, photo);
|
||||
g_free (name);
|
||||
|
||||
e_contact_address_free (address);
|
||||
}
|
||||
|
||||
if (photo)
|
||||
if (photo != NULL)
|
||||
e_contact_photo_free (photo);
|
||||
}
|
||||
|
||||
@@ -358,15 +344,33 @@ e_contact_map_add_marker (EContactMap *map,
|
||||
EContactPhoto *photo)
|
||||
{
|
||||
EContactMarker *marker;
|
||||
GHashTable *hash_table;
|
||||
GeocodeForward *geocoder;
|
||||
AsyncContext *async_context;
|
||||
|
||||
g_return_if_fail (map && E_IS_CONTACT_MAP (map));
|
||||
g_return_if_fail (name && *name);
|
||||
g_return_if_fail (contact_uid && *contact_uid);
|
||||
g_return_if_fail (address);
|
||||
g_return_if_fail (E_IS_CONTACT_MAP (map));
|
||||
g_return_if_fail (name != NULL);
|
||||
g_return_if_fail (contact_uid != NULL);
|
||||
g_return_if_fail (address != NULL);
|
||||
|
||||
marker = E_CONTACT_MARKER (e_contact_marker_new (name, contact_uid, photo));
|
||||
marker = e_contact_marker_new (name, contact_uid, photo);
|
||||
|
||||
resolve_marker_position (map, marker, address);
|
||||
hash_table = address_to_xep (address);
|
||||
geocoder = geocode_forward_new_for_params (hash_table);
|
||||
g_hash_table_destroy (hash_table);
|
||||
|
||||
async_context = g_slice_new0 (AsyncContext);
|
||||
async_context->map = g_object_ref (map);
|
||||
async_context->marker = marker;
|
||||
|
||||
geocode_forward_search_async (
|
||||
geocoder, NULL,
|
||||
contact_map_address_resolved_cb,
|
||||
async_context);
|
||||
|
||||
g_object_unref (geocoder);
|
||||
|
||||
g_signal_emit (map, signals[GEOCODING_STARTED], 0, marker);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -379,8 +383,8 @@ e_contact_map_remove_contact (EContactMap *map,
|
||||
{
|
||||
ChamplainMarker *marker;
|
||||
|
||||
g_return_if_fail (map && E_IS_CONTACT_MAP (map));
|
||||
g_return_if_fail (name && *name);
|
||||
g_return_if_fail (E_IS_CONTACT_MAP (map));
|
||||
g_return_if_fail (name != NULL);
|
||||
|
||||
marker = g_hash_table_lookup (map->priv->markers, name);
|
||||
|
||||
@@ -391,20 +395,6 @@ e_contact_map_remove_contact (EContactMap *map,
|
||||
g_signal_emit (map, signals[CONTACT_REMOVED], 0, name);
|
||||
}
|
||||
|
||||
void
|
||||
e_contact_map_remove_marker (EContactMap *map,
|
||||
ClutterActor *marker)
|
||||
{
|
||||
const gchar *name;
|
||||
|
||||
g_return_if_fail (map && E_IS_CONTACT_MAP (map));
|
||||
g_return_if_fail (marker && CLUTTER_IS_ACTOR (marker));
|
||||
|
||||
name = champlain_label_get_text (CHAMPLAIN_LABEL (marker));
|
||||
|
||||
e_contact_map_remove_contact (map, name);
|
||||
}
|
||||
|
||||
void
|
||||
e_contact_map_zoom_on_marker (EContactMap *map,
|
||||
ClutterActor *marker)
|
||||
@@ -412,8 +402,8 @@ e_contact_map_zoom_on_marker (EContactMap *map,
|
||||
ChamplainView *view;
|
||||
gdouble lat, lng;
|
||||
|
||||
g_return_if_fail (map && E_IS_CONTACT_MAP (map));
|
||||
g_return_if_fail (marker && CLUTTER_IS_ACTOR (marker));
|
||||
g_return_if_fail (E_IS_CONTACT_MAP (map));
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (marker));
|
||||
|
||||
lat = champlain_location_get_latitude (CHAMPLAIN_LOCATION (marker));
|
||||
lng = champlain_location_get_longitude (CHAMPLAIN_LOCATION (marker));
|
||||
|
||||
@@ -63,44 +63,34 @@ struct _EContactMap {
|
||||
struct _EContactMapClass {
|
||||
GtkWindowClass parent_class;
|
||||
|
||||
void (*contact_added) (EContactMap *map,
|
||||
ClutterActor *marker);
|
||||
|
||||
void (*contact_removed) (EContactMap *map,
|
||||
const gchar *name);
|
||||
|
||||
void (*geocoding_started) (EContactMap *map,
|
||||
ClutterActor *marker);
|
||||
|
||||
void (*geocoding_failed) (EContactMap *map,
|
||||
const gchar *name);
|
||||
/* Signals */
|
||||
void (*contact_added) (EContactMap *map,
|
||||
ClutterActor *marker);
|
||||
void (*contact_removed) (EContactMap *map,
|
||||
const gchar *name);
|
||||
void (*geocoding_started) (EContactMap *map,
|
||||
ClutterActor *marker);
|
||||
void (*geocoding_failed) (EContactMap *map,
|
||||
const gchar *name);
|
||||
};
|
||||
|
||||
GType e_contact_map_get_type (void) G_GNUC_CONST;
|
||||
GtkWidget * e_contact_map_new (void);
|
||||
|
||||
void e_contact_map_add_contact (EContactMap *map,
|
||||
EContact *contact);
|
||||
|
||||
void e_contact_map_add_marker (EContactMap *map,
|
||||
const gchar *name,
|
||||
const gchar *contact_uid,
|
||||
EContactAddress *address,
|
||||
EContactPhoto *photo);
|
||||
|
||||
void e_contact_map_remove_contact (EContactMap *map,
|
||||
const gchar *name);
|
||||
|
||||
void e_contact_map_remove_marker (EContactMap *map,
|
||||
ClutterActor *marker);
|
||||
|
||||
void e_contact_map_zoom_on_marker (EContactMap *map,
|
||||
ClutterActor *marker);
|
||||
|
||||
ChamplainView * e_contact_map_get_view (EContactMap *map);
|
||||
ChamplainView * e_contact_map_get_view (EContactMap *map);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* WITH_CONTACT_MAPS */
|
||||
|
||||
#endif
|
||||
#endif /* E_CONTACT_MAP_H */
|
||||
|
||||
@@ -39,13 +39,16 @@
|
||||
#include <string.h>
|
||||
|
||||
#define E_CONTACT_MARKER_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE \
|
||||
((obj), E_TYPE_CONTACT_MARKER, EContactMarkerPrivate))
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE \
|
||||
((obj), E_TYPE_CONTACT_MARKER, EContactMarkerPrivate))
|
||||
|
||||
G_DEFINE_TYPE (EContactMarker, e_contact_marker, CHAMPLAIN_TYPE_LABEL);
|
||||
#define DEFAULT_FONT_NAME "Serif 9"
|
||||
|
||||
struct _EContactMarkerPrivate
|
||||
{
|
||||
#define RADIUS 10
|
||||
#define PADDING (RADIUS / 2)
|
||||
#define HALF_PI (M_PI / 2.0)
|
||||
|
||||
struct _EContactMarkerPrivate {
|
||||
gchar *contact_uid;
|
||||
|
||||
ClutterActor *image;
|
||||
@@ -67,14 +70,14 @@ enum {
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static gint signals[LAST_SIGNAL] = {0};
|
||||
|
||||
#define DEFAULT_FONT_NAME "Serif 9"
|
||||
static gint signals[LAST_SIGNAL];
|
||||
|
||||
static ClutterColor DEFAULT_COLOR = { 0x33, 0x33, 0x33, 0xff };
|
||||
|
||||
#define RADIUS 10
|
||||
#define PADDING (RADIUS / 2)
|
||||
G_DEFINE_TYPE (
|
||||
EContactMarker,
|
||||
e_contact_marker,
|
||||
CHAMPLAIN_TYPE_LABEL);
|
||||
|
||||
static gboolean
|
||||
contact_marker_clicked_cb (ClutterActor *actor,
|
||||
@@ -84,7 +87,7 @@ contact_marker_clicked_cb (ClutterActor *actor,
|
||||
gint click_count = clutter_event_get_click_count (event);
|
||||
|
||||
if (click_count == 2)
|
||||
g_signal_emit (E_CONTACT_MARKER (actor), signals[DOUBLE_CLICKED], 0);
|
||||
g_signal_emit (actor, signals[DOUBLE_CLICKED], 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -157,12 +160,12 @@ draw_box (cairo_t *cr,
|
||||
{
|
||||
cairo_move_to (cr, RADIUS, 0);
|
||||
cairo_line_to (cr, width - RADIUS, 0);
|
||||
cairo_arc (cr, width - RADIUS, RADIUS, RADIUS - 1, 3 * M_PI / 2.0, 0);
|
||||
cairo_arc (cr, width - RADIUS, RADIUS, RADIUS - 1, 3 * HALF_PI, 0);
|
||||
cairo_line_to (cr, width, height - RADIUS);
|
||||
cairo_arc (cr, width - RADIUS, height - RADIUS, RADIUS - 1, 0, M_PI / 2.0);
|
||||
cairo_arc (cr, width - RADIUS, height - RADIUS, RADIUS - 1, 0, HALF_PI);
|
||||
cairo_line_to (cr, point, height);
|
||||
cairo_line_to (cr, 0, height + point);
|
||||
cairo_arc (cr, RADIUS, RADIUS, RADIUS - 1, M_PI, 3 * M_PI / 2.0);
|
||||
cairo_arc (cr, RADIUS, RADIUS, RADIUS - 1, M_PI, 3 * HALF_PI);
|
||||
cairo_close_path (cr);
|
||||
}
|
||||
|
||||
@@ -172,7 +175,6 @@ draw_shadow (EContactMarker *marker,
|
||||
gint height,
|
||||
gint point)
|
||||
{
|
||||
EContactMarkerPrivate *priv = marker->priv;
|
||||
ClutterActor *shadow = NULL;
|
||||
cairo_t *cr;
|
||||
gdouble slope;
|
||||
@@ -203,15 +205,16 @@ draw_shadow (EContactMarker *marker,
|
||||
|
||||
clutter_actor_set_position (shadow, 0, height / 2.0);
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (priv->content_group), shadow);
|
||||
clutter_container_add_actor (
|
||||
CLUTTER_CONTAINER (marker->priv->content_group), shadow);
|
||||
|
||||
if (priv->shadow != NULL) {
|
||||
if (marker->priv->shadow != NULL) {
|
||||
clutter_container_remove_actor (
|
||||
CLUTTER_CONTAINER (priv->content_group),
|
||||
priv->shadow);
|
||||
CLUTTER_CONTAINER (marker->priv->content_group),
|
||||
marker->priv->shadow);
|
||||
}
|
||||
|
||||
priv->shadow = shadow;
|
||||
marker->priv->shadow = shadow;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -233,7 +236,7 @@ draw_background (EContactMarker *marker,
|
||||
cairo_paint (cr);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
||||
|
||||
/* If selected, add the selection color to the marker's color */
|
||||
/* If selected, add the selection color to the marker's color */
|
||||
if (champlain_marker_get_selected (CHAMPLAIN_MARKER (marker)))
|
||||
color = champlain_marker_get_selection_color ();
|
||||
else
|
||||
@@ -275,28 +278,28 @@ draw_background (EContactMarker *marker,
|
||||
static void
|
||||
draw_marker (EContactMarker *marker)
|
||||
{
|
||||
EContactMarkerPrivate *priv = marker->priv;
|
||||
ChamplainLabel *label = CHAMPLAIN_LABEL (marker);
|
||||
guint height = 0, point = 0;
|
||||
guint total_width = 0, total_height = 0;
|
||||
ClutterText *text;
|
||||
|
||||
if (priv->image) {
|
||||
clutter_actor_set_position (priv->image, 2 *PADDING, 2 *PADDING);
|
||||
if (clutter_actor_get_parent (priv->image) == NULL)
|
||||
if (marker->priv->image != NULL) {
|
||||
clutter_actor_set_position (
|
||||
marker->priv->image, 2 * PADDING, 2 * PADDING);
|
||||
if (clutter_actor_get_parent (marker->priv->image) == NULL)
|
||||
clutter_container_add_actor (
|
||||
CLUTTER_CONTAINER (priv->content_group),
|
||||
priv->image);
|
||||
CLUTTER_CONTAINER (marker->priv->content_group),
|
||||
marker->priv->image);
|
||||
}
|
||||
|
||||
if (priv->text_actor == NULL) {
|
||||
priv->text_actor = clutter_text_new_with_text (
|
||||
if (marker->priv->text_actor == NULL) {
|
||||
marker->priv->text_actor = clutter_text_new_with_text (
|
||||
"Serif 8",
|
||||
champlain_label_get_text (label));
|
||||
champlain_label_set_font_name (label, "Serif 8");
|
||||
}
|
||||
|
||||
text = CLUTTER_TEXT (priv->text_actor);
|
||||
text = CLUTTER_TEXT (marker->priv->text_actor);
|
||||
clutter_text_set_text (
|
||||
text,
|
||||
champlain_label_get_text (label));
|
||||
@@ -316,20 +319,42 @@ draw_marker (EContactMarker *marker)
|
||||
text,
|
||||
champlain_label_get_use_markup (label));
|
||||
|
||||
if (priv->image) {
|
||||
if (marker->priv->image != NULL) {
|
||||
gfloat image_height;
|
||||
gfloat image_width;
|
||||
gfloat text_height;
|
||||
|
||||
image_height = clutter_actor_get_height (marker->priv->image);
|
||||
image_width = clutter_actor_get_width (marker->priv->image);
|
||||
|
||||
clutter_actor_set_width (
|
||||
priv->text_actor,
|
||||
clutter_actor_get_width (priv->image));
|
||||
total_height = clutter_actor_get_height (priv->image) + 2 *PADDING +
|
||||
clutter_actor_get_height (priv->text_actor) + 2 *PADDING;
|
||||
total_width = clutter_actor_get_width (priv->image) + 4 *PADDING;
|
||||
marker->priv->text_actor, image_width);
|
||||
text_height = clutter_actor_get_height (
|
||||
marker->priv->text_actor);
|
||||
|
||||
total_height =
|
||||
text_height + 2 * PADDING +
|
||||
image_height + 2 * PADDING;
|
||||
total_width = image_width + 4 * PADDING;
|
||||
|
||||
clutter_actor_set_position (
|
||||
priv->text_actor, PADDING,
|
||||
clutter_actor_get_height (priv->image) + 2 *PADDING + 3);
|
||||
marker->priv->text_actor,
|
||||
PADDING, image_height + 2 * PADDING + 3);
|
||||
} else {
|
||||
total_height = clutter_actor_get_height (priv->text_actor) + 2 *PADDING;
|
||||
total_width = clutter_actor_get_width (priv->text_actor) + 4 *PADDING;
|
||||
clutter_actor_set_position (priv->text_actor, 2 * PADDING, PADDING);
|
||||
gfloat text_height;
|
||||
gfloat text_width;
|
||||
|
||||
text_height = clutter_actor_get_height (
|
||||
marker->priv->text_actor);
|
||||
text_width = clutter_actor_get_width (
|
||||
marker->priv->text_actor);
|
||||
|
||||
total_height = text_height + 2 * PADDING;
|
||||
total_width = text_width + 4 * PADDING;
|
||||
|
||||
clutter_actor_set_position (
|
||||
marker->priv->text_actor,
|
||||
2 * PADDING, PADDING);
|
||||
}
|
||||
|
||||
height += 2 * PADDING;
|
||||
@@ -337,33 +362,40 @@ draw_marker (EContactMarker *marker)
|
||||
total_height = height;
|
||||
|
||||
clutter_text_set_color (
|
||||
CLUTTER_TEXT (priv->text_actor),
|
||||
CLUTTER_TEXT (marker->priv->text_actor),
|
||||
(champlain_marker_get_selected (CHAMPLAIN_MARKER (marker)) ?
|
||||
champlain_marker_get_selection_text_color () :
|
||||
champlain_label_get_text_color (CHAMPLAIN_LABEL (marker))));
|
||||
if (clutter_actor_get_parent (priv->text_actor) == NULL)
|
||||
if (clutter_actor_get_parent (marker->priv->text_actor) == NULL)
|
||||
clutter_container_add_actor (
|
||||
CLUTTER_CONTAINER (priv->content_group),
|
||||
priv->text_actor);
|
||||
CLUTTER_CONTAINER (marker->priv->content_group),
|
||||
marker->priv->text_actor);
|
||||
|
||||
if (priv->text_actor == NULL && priv->image == NULL) {
|
||||
if (marker->priv->text_actor == NULL && marker->priv->image == NULL) {
|
||||
total_width = 6 * PADDING;
|
||||
total_height = 6 * PADDING;
|
||||
}
|
||||
|
||||
point = (total_height + 2 * PADDING) / 4.0;
|
||||
priv->total_width = total_width;
|
||||
priv->total_height = total_height;
|
||||
marker->priv->total_width = total_width;
|
||||
marker->priv->total_height = total_height;
|
||||
|
||||
draw_shadow (marker, total_width, total_height, point);
|
||||
draw_background (marker, total_width, total_height, point);
|
||||
|
||||
if (priv->text_actor != NULL && priv->background != NULL)
|
||||
clutter_actor_raise (priv->text_actor, priv->background);
|
||||
if (priv->image != NULL && priv->background != NULL)
|
||||
clutter_actor_raise (priv->image, priv->background);
|
||||
if (marker->priv->background != NULL) {
|
||||
if (marker->priv->text_actor != NULL)
|
||||
clutter_actor_raise (
|
||||
marker->priv->text_actor,
|
||||
marker->priv->background);
|
||||
if (marker->priv->image != NULL)
|
||||
clutter_actor_raise (
|
||||
marker->priv->image,
|
||||
marker->priv->background);
|
||||
}
|
||||
|
||||
clutter_actor_set_anchor_point (CLUTTER_ACTOR (marker), 0, total_height + point);
|
||||
clutter_actor_set_anchor_point (
|
||||
CLUTTER_ACTOR (marker), 0, total_height + point);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -391,62 +423,101 @@ queue_redraw (EContactMarker *marker)
|
||||
}
|
||||
|
||||
static void
|
||||
allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags)
|
||||
notify_selected (GObject *gobject,
|
||||
G_GNUC_UNUSED GParamSpec *pspec,
|
||||
G_GNUC_UNUSED gpointer user_data)
|
||||
{
|
||||
ClutterActorBox child_box;
|
||||
EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
|
||||
|
||||
CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->allocate (self, box, flags);
|
||||
|
||||
child_box.x1 = 0;
|
||||
child_box.x2 = box->x2 - box->x1;
|
||||
child_box.y1 = 0;
|
||||
child_box.y2 = box->y2 - box->y1;
|
||||
clutter_actor_allocate (CLUTTER_ACTOR (priv->content_group), &child_box, flags);
|
||||
queue_redraw (E_CONTACT_MARKER (gobject));
|
||||
}
|
||||
|
||||
static void
|
||||
paint (ClutterActor *self)
|
||||
contact_marker_dispose (GObject *object)
|
||||
{
|
||||
EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
|
||||
EContactMarkerPrivate *priv;
|
||||
|
||||
clutter_actor_paint (CLUTTER_ACTOR (priv->content_group));
|
||||
priv = E_CONTACT_MARKER_GET_PRIVATE (object);
|
||||
|
||||
priv->background = NULL;
|
||||
priv->shadow = NULL;
|
||||
priv->text_actor = NULL;
|
||||
|
||||
if (priv->redraw_id > 0) {
|
||||
g_source_remove (priv->redraw_id);
|
||||
priv->redraw_id = 0;
|
||||
}
|
||||
|
||||
if (priv->content_group != NULL) {
|
||||
clutter_actor_unparent (CLUTTER_ACTOR (priv->content_group));
|
||||
priv->content_group = NULL;
|
||||
}
|
||||
|
||||
/* Chain up to parent's dispose() method. */
|
||||
G_OBJECT_CLASS (e_contact_marker_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
map (ClutterActor *self)
|
||||
contact_marker_finalize (GObject *object)
|
||||
{
|
||||
EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
|
||||
EContactMarkerPrivate *priv;
|
||||
|
||||
CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->map (self);
|
||||
priv = E_CONTACT_MARKER_GET_PRIVATE (object);
|
||||
|
||||
clutter_actor_map (CLUTTER_ACTOR (priv->content_group));
|
||||
g_free (priv->contact_uid);
|
||||
|
||||
/* Chain up to parent's finalize() method. */
|
||||
G_OBJECT_CLASS (e_contact_marker_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
unmap (ClutterActor *self)
|
||||
contact_marker_map (ClutterActor *actor)
|
||||
{
|
||||
EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
|
||||
EContactMarker *marker;
|
||||
|
||||
CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->unmap (self);
|
||||
marker = E_CONTACT_MARKER (actor);
|
||||
|
||||
clutter_actor_unmap (CLUTTER_ACTOR (priv->content_group));
|
||||
/* Chain up to parent's map() method. */
|
||||
CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->map (actor);
|
||||
|
||||
clutter_actor_map (CLUTTER_ACTOR (marker->priv->content_group));
|
||||
}
|
||||
|
||||
static void
|
||||
pick (ClutterActor *self,
|
||||
const ClutterColor *color)
|
||||
contact_marker_unmap (ClutterActor *actor)
|
||||
{
|
||||
EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
|
||||
EContactMarker *marker;
|
||||
|
||||
marker = E_CONTACT_MARKER (actor);
|
||||
|
||||
/* Chain up to parent's unmap() method. */
|
||||
CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->unmap (actor);
|
||||
|
||||
clutter_actor_unmap (CLUTTER_ACTOR (marker->priv->content_group));
|
||||
}
|
||||
|
||||
static void
|
||||
contact_marker_paint (ClutterActor *actor)
|
||||
{
|
||||
EContactMarker *marker;
|
||||
|
||||
marker = E_CONTACT_MARKER (actor);
|
||||
|
||||
clutter_actor_paint (CLUTTER_ACTOR (marker->priv->content_group));
|
||||
}
|
||||
|
||||
static void
|
||||
contact_marker_pick (ClutterActor *actor,
|
||||
const ClutterColor *color)
|
||||
{
|
||||
EContactMarker *marker;
|
||||
gfloat width, height;
|
||||
|
||||
if (!clutter_actor_should_pick_paint (self))
|
||||
if (!clutter_actor_should_pick_paint (actor))
|
||||
return;
|
||||
|
||||
width = priv->total_width;
|
||||
height = priv->total_height;
|
||||
marker = E_CONTACT_MARKER (actor);
|
||||
|
||||
width = marker->priv->total_width;
|
||||
height = marker->priv->total_height;
|
||||
|
||||
cogl_path_new ();
|
||||
|
||||
@@ -470,64 +541,47 @@ pick (ClutterActor *self,
|
||||
}
|
||||
|
||||
static void
|
||||
notify_selected (GObject *gobject,
|
||||
G_GNUC_UNUSED GParamSpec *pspec,
|
||||
G_GNUC_UNUSED gpointer user_data)
|
||||
contact_marker_allocate (ClutterActor *actor,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags)
|
||||
{
|
||||
queue_redraw (E_CONTACT_MARKER (gobject));
|
||||
}
|
||||
EContactMarker *marker;
|
||||
ClutterActorBox child_box;
|
||||
|
||||
static void
|
||||
e_contact_marker_finalize (GObject *object)
|
||||
{
|
||||
EContactMarkerPrivate *priv = E_CONTACT_MARKER (object)->priv;
|
||||
marker = E_CONTACT_MARKER (actor);
|
||||
|
||||
if (priv->contact_uid) {
|
||||
g_free (priv->contact_uid);
|
||||
priv->contact_uid = NULL;
|
||||
}
|
||||
/* Chain up to parent's allocate() method. */
|
||||
CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->
|
||||
allocate (actor, box, flags);
|
||||
|
||||
if (priv->redraw_id) {
|
||||
g_source_remove (priv->redraw_id);
|
||||
priv->redraw_id = 0;
|
||||
}
|
||||
child_box.x1 = 0;
|
||||
child_box.x2 = box->x2 - box->x1;
|
||||
child_box.y1 = 0;
|
||||
child_box.y2 = box->y2 - box->y1;
|
||||
|
||||
G_OBJECT_CLASS (e_contact_marker_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
e_contact_marker_dispose (GObject *object)
|
||||
{
|
||||
EContactMarkerPrivate *priv = E_CONTACT_MARKER (object)->priv;
|
||||
|
||||
priv->background = NULL;
|
||||
priv->shadow = NULL;
|
||||
priv->text_actor = NULL;
|
||||
|
||||
if (priv->content_group) {
|
||||
clutter_actor_unparent (CLUTTER_ACTOR (priv->content_group));
|
||||
priv->content_group = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (e_contact_marker_parent_class)->dispose (object);
|
||||
clutter_actor_allocate (
|
||||
CLUTTER_ACTOR (marker->priv->content_group),
|
||||
&child_box, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
e_contact_marker_class_init (EContactMarkerClass *class)
|
||||
{
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (class);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GObjectClass *object_class;
|
||||
ClutterActorClass *actor_class;
|
||||
|
||||
g_type_class_add_private (class, sizeof (EContactMarkerPrivate));
|
||||
|
||||
object_class->dispose = e_contact_marker_dispose;
|
||||
object_class->finalize = e_contact_marker_finalize;
|
||||
object_class = G_OBJECT_CLASS (class);
|
||||
object_class->dispose = contact_marker_dispose;
|
||||
object_class->finalize = contact_marker_finalize;
|
||||
|
||||
actor_class->paint = paint;
|
||||
actor_class->allocate = allocate;
|
||||
actor_class->map = map;
|
||||
actor_class->unmap = unmap;
|
||||
actor_class->pick = pick;
|
||||
actor_class = CLUTTER_ACTOR_CLASS (class);
|
||||
actor_class->map = contact_marker_map;
|
||||
actor_class->unmap = contact_marker_unmap;
|
||||
actor_class->paint = contact_marker_paint;
|
||||
actor_class->pick = contact_marker_pick;
|
||||
actor_class->allocate = contact_marker_allocate;
|
||||
|
||||
signals[DOUBLE_CLICKED] = g_signal_new (
|
||||
"double-clicked",
|
||||
@@ -542,26 +596,15 @@ e_contact_marker_class_init (EContactMarkerClass *class)
|
||||
static void
|
||||
e_contact_marker_init (EContactMarker *marker)
|
||||
{
|
||||
EContactMarkerPrivate *priv;
|
||||
marker->priv = E_CONTACT_MARKER_GET_PRIVATE (marker);
|
||||
|
||||
priv = E_CONTACT_MARKER_GET_PRIVATE (marker);
|
||||
|
||||
marker->priv = priv;
|
||||
priv->contact_uid = NULL;
|
||||
priv->image = NULL;
|
||||
priv->background = NULL;
|
||||
priv->shadow = NULL;
|
||||
priv->text_actor = NULL;
|
||||
priv->content_group = CLUTTER_GROUP (clutter_group_new ());
|
||||
priv->redraw_id = 0;
|
||||
marker->priv->content_group = CLUTTER_GROUP (clutter_group_new ());
|
||||
|
||||
clutter_actor_set_parent (
|
||||
CLUTTER_ACTOR (priv->content_group), CLUTTER_ACTOR (marker));
|
||||
CLUTTER_ACTOR (marker->priv->content_group),
|
||||
CLUTTER_ACTOR (marker));
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (marker));
|
||||
|
||||
priv->total_width = 0;
|
||||
priv->total_height = 0;
|
||||
|
||||
g_signal_connect (
|
||||
marker, "notify::selected",
|
||||
G_CALLBACK (notify_selected), NULL);
|
||||
@@ -570,23 +613,24 @@ e_contact_marker_init (EContactMarker *marker)
|
||||
G_CALLBACK (contact_marker_clicked_cb), NULL);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
EContactMarker *
|
||||
e_contact_marker_new (const gchar *name,
|
||||
const gchar *contact_uid,
|
||||
EContactPhoto *photo)
|
||||
{
|
||||
ClutterActor *marker = CLUTTER_ACTOR (g_object_new (E_TYPE_CONTACT_MARKER, NULL));
|
||||
EContactMarkerPrivate *priv = E_CONTACT_MARKER (marker)->priv;
|
||||
EContactMarker *marker;
|
||||
|
||||
g_return_val_if_fail (name && *name, NULL);
|
||||
g_return_val_if_fail (contact_uid && *contact_uid, NULL);
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
g_return_val_if_fail (contact_uid != NULL, NULL);
|
||||
|
||||
marker = g_object_new (E_TYPE_CONTACT_MARKER, NULL);
|
||||
|
||||
champlain_label_set_text (CHAMPLAIN_LABEL (marker), name);
|
||||
priv->contact_uid = g_strdup (contact_uid);
|
||||
if (photo)
|
||||
priv->image = contact_photo_to_texture (photo);
|
||||
marker->priv->contact_uid = g_strdup (contact_uid);
|
||||
if (photo != NULL)
|
||||
marker->priv->image = contact_photo_to_texture (photo);
|
||||
|
||||
queue_redraw (E_CONTACT_MARKER (marker));
|
||||
queue_redraw (marker);
|
||||
|
||||
return marker;
|
||||
}
|
||||
@@ -594,7 +638,7 @@ e_contact_marker_new (const gchar *name,
|
||||
const gchar *
|
||||
e_contact_marker_get_contact_uid (EContactMarker *marker)
|
||||
{
|
||||
g_return_val_if_fail (marker && E_IS_CONTACT_MARKER (marker), NULL);
|
||||
g_return_val_if_fail (E_IS_CONTACT_MARKER (marker), NULL);
|
||||
|
||||
return marker->priv->contact_uid;
|
||||
}
|
||||
|
||||
@@ -25,60 +25,57 @@
|
||||
|
||||
#ifdef WITH_CONTACT_MAPS
|
||||
|
||||
#include <libebook/libebook.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <champlain/champlain.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <libebook/libebook.h>
|
||||
|
||||
/* Standard GObject macros */
|
||||
#define E_TYPE_CONTACT_MARKER \
|
||||
(e_contact_marker_get_type ())
|
||||
#define E_CONTACT_MARKER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST \
|
||||
((obj), E_TYPE_CONTACT_MARKER, EContactMarker))
|
||||
#define E_CONTACT_MARKER_CLASS(cls) \
|
||||
(G_TYPE_CHECK_CLASS_CAST \
|
||||
((cls), E_TYPE_CONTACT_MARKER, EContactMarkerClass))
|
||||
#define E_IS_CONTACT_MARKER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE \
|
||||
((obj), E_TYPE_CONTACT_MARKER))
|
||||
#define E_IS_CONTACT_MARKER_CLASS(cls) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE \
|
||||
((cls), E_TYPE_CONTACT_MARKER))
|
||||
#define E_CONTACT_MARKER_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS \
|
||||
((obj), E_TYPE_CONTACT_MARKER, EContactMarkerClass))
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define E_TYPE_CONTACT_MARKER e_contact_marker_get_type ()
|
||||
|
||||
#define E_CONTACT_MARKER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CONTACT_MARKER, EContactMarker))
|
||||
|
||||
#define E_CONTACT_MARKER_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CONTACT_MARKER, EContactMarkerClass))
|
||||
|
||||
#define E_IS_CONTACT_MARKER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CONTACT_MARKER))
|
||||
|
||||
#define E_IS_CONTACT_MARKER_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CONTACT_MARKER))
|
||||
|
||||
#define E_CONTACT_MARKER_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CONTACT_MARKER, EContactMarkerClass))
|
||||
|
||||
typedef struct _EContactMarkerPrivate EContactMarkerPrivate;
|
||||
|
||||
typedef struct _EContactMarker EContactMarker;
|
||||
typedef struct _EContactMarkerClass EContactMarkerClass;
|
||||
typedef struct _EContactMarkerPrivate EContactMarkerPrivate;
|
||||
|
||||
struct _EContactMarker
|
||||
{
|
||||
struct _EContactMarker {
|
||||
ChamplainLabel parent;
|
||||
EContactMarkerPrivate *priv;
|
||||
};
|
||||
|
||||
struct _EContactMarkerClass
|
||||
{
|
||||
struct _EContactMarkerClass {
|
||||
ChamplainLabelClass parent_class;
|
||||
|
||||
void (*double_clicked) (ClutterActor *actor);
|
||||
};
|
||||
|
||||
GType e_contact_marker_get_type (void);
|
||||
|
||||
ClutterActor * e_contact_marker_new (const gchar *name,
|
||||
GType e_contact_marker_get_type (void) G_GNUC_CONST;
|
||||
EContactMarker *
|
||||
e_contact_marker_new (const gchar *name,
|
||||
const gchar *contact_uid,
|
||||
EContactPhoto *photo);
|
||||
|
||||
const gchar * e_contact_marker_get_contact_uid (EContactMarker *marker);
|
||||
const gchar * e_contact_marker_get_contact_uid
|
||||
(EContactMarker *marker);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* WITH_CONTACT_MAPS */
|
||||
|
||||
#endif
|
||||
#endif /* E_CONTACT_MARKER_H */
|
||||
|
||||
Reference in New Issue
Block a user