Move Shell search to GcalShellSearchProvider
Add a custom timeline to GcalShellSearchProvier and use it to gather events. Do a massive cleanup of unused APIs as well.
This commit is contained in:
@@ -84,6 +84,7 @@ struct _GcalCalendarMonitor
|
||||
static gboolean add_event_to_timeline_in_idle_cb (gpointer user_data);
|
||||
static gboolean update_event_in_idle_cb (gpointer user_data);
|
||||
static gboolean remove_event_from_timeline_in_idle_cb (gpointer user_data);
|
||||
static gboolean complete_in_idle_cb (gpointer user_data);
|
||||
|
||||
G_DEFINE_TYPE (GcalCalendarMonitor, gcal_calendar_monitor, G_TYPE_OBJECT)
|
||||
|
||||
@@ -92,6 +93,7 @@ enum
|
||||
EVENT_ADDED,
|
||||
EVENT_UPDATED,
|
||||
EVENT_REMOVED,
|
||||
COMPLETED,
|
||||
N_SIGNALS,
|
||||
};
|
||||
|
||||
@@ -241,6 +243,21 @@ remove_event_in_idle (GcalCalendarMonitor *self,
|
||||
(GDestroyNotify) idle_data_free);
|
||||
}
|
||||
|
||||
static void
|
||||
complete_in_idle (GcalCalendarMonitor *self)
|
||||
{
|
||||
IdleData *idle_data;
|
||||
|
||||
idle_data = g_new0 (IdleData, 1);
|
||||
idle_data->monitor = g_object_ref (self);
|
||||
|
||||
g_main_context_invoke_full (self->main_context,
|
||||
G_PRIORITY_DEFAULT_IDLE,
|
||||
complete_in_idle_cb,
|
||||
idle_data,
|
||||
(GDestroyNotify) idle_data_free);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GcalCalendarMonitor *monitor;
|
||||
@@ -568,6 +585,8 @@ on_client_view_complete_cb (ECalClientView *view,
|
||||
|
||||
self->monitor_thread.populated = TRUE;
|
||||
|
||||
complete_in_idle (self);
|
||||
|
||||
g_debug ("Finished initial loading of calendar '%s'", gcal_calendar_get_name (self->calendar));
|
||||
|
||||
GCAL_EXIT;
|
||||
@@ -939,6 +958,24 @@ on_calendar_visible_changed_cb (GcalCalendar *calendar,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
complete_in_idle_cb (gpointer user_data)
|
||||
{
|
||||
g_autoptr (GcalEvent) event = NULL;
|
||||
GcalCalendarMonitor *self;
|
||||
IdleData *idle_data;
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
idle_data = user_data;
|
||||
self = idle_data->monitor;
|
||||
g_assert (idle_data->event == NULL);
|
||||
g_assert (idle_data->event_id == NULL);
|
||||
|
||||
g_signal_emit (self, signals[COMPLETED], 0, event);
|
||||
GCAL_RETURN (G_SOURCE_REMOVE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GObject overrides
|
||||
@@ -1044,6 +1081,13 @@ gcal_calendar_monitor_class_init (GcalCalendarMonitorClass *klass)
|
||||
1,
|
||||
GCAL_TYPE_EVENT);
|
||||
|
||||
signals[COMPLETED] = g_signal_new ("completed",
|
||||
GCAL_TYPE_CALENDAR_MONITOR,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
|
||||
properties[PROP_CALENDAR] = g_param_spec_object ("calendar",
|
||||
"Calendar",
|
||||
"Calendar to be monitores",
|
||||
|
||||
@@ -45,16 +45,6 @@ typedef struct
|
||||
GcalManager *manager;
|
||||
} AsyncOpsData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ECalDataModelSubscriber *subscriber;
|
||||
gchar *query;
|
||||
|
||||
guint sources_left;
|
||||
gboolean passed_start;
|
||||
gboolean search_done;
|
||||
} ViewStateData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *event_uid;
|
||||
@@ -64,12 +54,6 @@ typedef struct
|
||||
GcalManager *manager;
|
||||
} MoveEventData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GcalManager *manager;
|
||||
GList *events;
|
||||
} GatherEventData;
|
||||
|
||||
struct _GcalManager
|
||||
{
|
||||
GObject parent;
|
||||
@@ -84,9 +68,6 @@ struct _GcalManager
|
||||
ESourceRegistry *source_registry;
|
||||
ECredentialsPrompter *credentials_prompter;
|
||||
|
||||
ECalDataModel *shell_search_data_model;
|
||||
ViewStateData *search_view_data;
|
||||
|
||||
GCancellable *async_ops;
|
||||
|
||||
gint clients_synchronizing;
|
||||
@@ -126,36 +107,6 @@ free_async_ops_data (AsyncOpsData *data)
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gather_events (ECalDataModel *data_model,
|
||||
ECalClient *client,
|
||||
const ECalComponentId *id,
|
||||
ECalComponent *comp,
|
||||
time_t instance_start,
|
||||
time_t instance_end,
|
||||
gpointer user_data)
|
||||
{
|
||||
GatherEventData *data = user_data;
|
||||
GcalCalendar *calendar;
|
||||
GcalEvent *event;
|
||||
GError *error;
|
||||
|
||||
error = NULL;
|
||||
calendar = g_hash_table_lookup (data->manager->clients, e_client_get_source (E_CLIENT (client)));
|
||||
event = gcal_event_new (calendar, comp, &error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_warning ("Error: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
data->events = g_list_append (data->events, event);/* FIXME: add me sorted */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_source (GcalManager *self,
|
||||
ESource *source)
|
||||
@@ -198,21 +149,6 @@ source_changed (GcalManager *self,
|
||||
if (!calendar)
|
||||
GCAL_RETURN ();
|
||||
|
||||
if (gcal_calendar_get_visible (calendar))
|
||||
{
|
||||
ECalClient *client = gcal_calendar_get_client (calendar);
|
||||
|
||||
if (self->shell_search_data_model)
|
||||
e_cal_data_model_add_client (self->shell_search_data_model, client);
|
||||
}
|
||||
else
|
||||
{
|
||||
const gchar *id = gcal_calendar_get_id (calendar);
|
||||
|
||||
if (self->shell_search_data_model)
|
||||
e_cal_data_model_remove_client (self->shell_search_data_model, id);
|
||||
}
|
||||
|
||||
g_signal_emit (self, signals[CALENDAR_CHANGED], 0, calendar);
|
||||
|
||||
GCAL_EXIT;
|
||||
@@ -286,12 +222,6 @@ on_calendar_created_cb (GObject *source_object,
|
||||
|
||||
gcal_timeline_add_calendar (self->timeline, calendar);
|
||||
|
||||
if (visible)
|
||||
{
|
||||
if (self->shell_search_data_model != NULL)
|
||||
e_cal_data_model_add_client (self->shell_search_data_model, client);
|
||||
}
|
||||
|
||||
/* refresh client when it's added */
|
||||
if (visible && e_client_check_refresh_supported (E_CLIENT (client)))
|
||||
{
|
||||
@@ -464,45 +394,6 @@ on_event_removed (GObject *source_object,
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
model_state_changed (GcalManager *self,
|
||||
ECalClientView *view,
|
||||
ECalDataModelViewState state,
|
||||
guint percent,
|
||||
const gchar *message,
|
||||
const GError *error,
|
||||
ECalDataModel *data_model)
|
||||
{
|
||||
gchar *filter;
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
filter = e_cal_data_model_dup_filter (data_model);
|
||||
|
||||
if (state == E_CAL_DATA_MODEL_VIEW_STATE_START &&
|
||||
g_strcmp0 (self->search_view_data->query, filter) == 0)
|
||||
{
|
||||
self->search_view_data->passed_start = TRUE;
|
||||
GCAL_GOTO (out);
|
||||
}
|
||||
|
||||
if (self->search_view_data->passed_start &&
|
||||
state == E_CAL_DATA_MODEL_VIEW_STATE_COMPLETE &&
|
||||
g_strcmp0 (self->search_view_data->query, filter) == 0)
|
||||
{
|
||||
self->search_view_data->sources_left--;
|
||||
self->search_view_data->search_done = (self->search_view_data->sources_left == 0);
|
||||
|
||||
if (self->search_view_data->search_done)
|
||||
g_signal_emit (self, signals[QUERY_COMPLETED], 0);
|
||||
}
|
||||
|
||||
out:
|
||||
g_free (filter);
|
||||
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
show_source_error (const gchar *where,
|
||||
const gchar *what,
|
||||
@@ -653,7 +544,6 @@ gcal_manager_finalize (GObject *object)
|
||||
GCAL_ENTRY;
|
||||
|
||||
g_clear_object (&self->timeline);
|
||||
g_clear_object (&self->shell_search_data_model);
|
||||
|
||||
if (self->context)
|
||||
{
|
||||
@@ -661,12 +551,6 @@ gcal_manager_finalize (GObject *object)
|
||||
self->context = NULL;
|
||||
}
|
||||
|
||||
if (self->search_view_data)
|
||||
{
|
||||
g_clear_pointer (&self->search_view_data->query, g_free);
|
||||
g_clear_pointer (&self->search_view_data, g_free);
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->clients, g_hash_table_destroy);
|
||||
|
||||
G_OBJECT_CLASS (gcal_manager_parent_class)->finalize (object);
|
||||
@@ -903,137 +787,6 @@ gcal_manager_set_default_calendar (GcalManager *self,
|
||||
gcal_calendar_get_source (calendar));
|
||||
}
|
||||
|
||||
/**
|
||||
* gcal_manager_setup_shell_search:
|
||||
* @self: a #GcalManager
|
||||
* @subscriber: an #ECalDataModelSubscriber
|
||||
*
|
||||
* Sets up the GNOME Shell search subscriber.
|
||||
*/
|
||||
void
|
||||
gcal_manager_setup_shell_search (GcalManager *self,
|
||||
ECalDataModelSubscriber *subscriber)
|
||||
{
|
||||
GTimeZone *zone;
|
||||
|
||||
g_return_if_fail (GCAL_IS_MANAGER (self));
|
||||
|
||||
if (self->shell_search_data_model)
|
||||
return;
|
||||
|
||||
self->shell_search_data_model = e_cal_data_model_new (gcal_thread_submit_job);
|
||||
g_signal_connect_object (self->shell_search_data_model,
|
||||
"view-state-changed",
|
||||
G_CALLBACK (model_state_changed),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
e_cal_data_model_set_expand_recurrences (self->shell_search_data_model, TRUE);
|
||||
|
||||
zone = gcal_context_get_timezone (self->context);
|
||||
e_cal_data_model_set_timezone (self->shell_search_data_model, gcal_timezone_to_icaltimezone (zone));
|
||||
|
||||
self->search_view_data = g_new0 (ViewStateData, 1);
|
||||
self->search_view_data->subscriber = subscriber;
|
||||
}
|
||||
|
||||
/**
|
||||
* gcal_manager_set_shell_search_query:
|
||||
* @self: A #GcalManager instance
|
||||
* @query: query string (an s-exp)
|
||||
*
|
||||
* Set the query terms of the #ECalDataModel used in the shell search
|
||||
*/
|
||||
void
|
||||
gcal_manager_set_shell_search_query (GcalManager *self,
|
||||
const gchar *query)
|
||||
{
|
||||
GCAL_ENTRY;
|
||||
|
||||
g_return_if_fail (GCAL_IS_MANAGER (self));
|
||||
|
||||
self->search_view_data->passed_start = FALSE;
|
||||
self->search_view_data->search_done = FALSE;
|
||||
self->search_view_data->sources_left = g_hash_table_size (self->clients);
|
||||
|
||||
if (self->search_view_data->query != NULL)
|
||||
g_free (self->search_view_data->query);
|
||||
self->search_view_data->query = g_strdup (query);
|
||||
|
||||
e_cal_data_model_set_filter (self->shell_search_data_model, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* gcal_manager_set_shell_search_subscriber:
|
||||
* @self: a #GcalManager
|
||||
* @subscriber: the #ECalDataModelSubscriber to subscribe
|
||||
* @range_start: the start of the range
|
||||
* @range_end: the end of the range
|
||||
*
|
||||
* Subscribe @subscriber to the shell data modal at the given range.
|
||||
*/
|
||||
void
|
||||
gcal_manager_set_shell_search_subscriber (GcalManager *self,
|
||||
ECalDataModelSubscriber *subscriber,
|
||||
time_t range_start,
|
||||
time_t range_end)
|
||||
{
|
||||
GCAL_ENTRY;
|
||||
|
||||
e_cal_data_model_subscribe (self->shell_search_data_model, subscriber, range_start, range_end);
|
||||
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* gcal_manager_shell_search_done:
|
||||
* @self: a #GcalManager
|
||||
*
|
||||
* Retrieves whether the search at @self is done or not.
|
||||
*
|
||||
* Returns: %TRUE if the search is finished.
|
||||
*/
|
||||
gboolean
|
||||
gcal_manager_shell_search_done (GcalManager *self)
|
||||
{
|
||||
g_return_val_if_fail (GCAL_IS_MANAGER (self), FALSE);
|
||||
|
||||
return self->search_view_data->search_done;
|
||||
}
|
||||
|
||||
/**
|
||||
* gcal_manager_get_shell_search_events:
|
||||
* @self: a #GcalManager
|
||||
*
|
||||
* Retrieves all the events available for GNOME Shell search.
|
||||
*
|
||||
* Returns: (nullable)(transfer full)(content-type GcalEvent): a #GList
|
||||
*/
|
||||
GList*
|
||||
gcal_manager_get_shell_search_events (GcalManager *self)
|
||||
{
|
||||
time_t range_start, range_end;
|
||||
GatherEventData data = {
|
||||
.manager = self,
|
||||
.events = NULL,
|
||||
};
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
e_cal_data_model_get_subscriber_range (self->shell_search_data_model,
|
||||
self->search_view_data->subscriber,
|
||||
&range_start,
|
||||
&range_end);
|
||||
|
||||
e_cal_data_model_foreach_component (self->shell_search_data_model,
|
||||
range_start,
|
||||
range_end,
|
||||
gather_events,
|
||||
&data);
|
||||
|
||||
GCAL_RETURN (data.events);
|
||||
}
|
||||
|
||||
/**
|
||||
* gcal_manager_set_subscriber:
|
||||
* @self: a #GcalManager
|
||||
@@ -1469,63 +1222,6 @@ gcal_manager_get_events (GcalManager *self,
|
||||
GCAL_RETURN (g_steal_pointer (&events_at_range));
|
||||
}
|
||||
|
||||
/**
|
||||
* gcal_manager_get_event_from_shell_search:
|
||||
* @self: a #GcalManager
|
||||
* @uuid: the unique identier of the event
|
||||
*
|
||||
* Retrieves the #GcalEvent with @uuid.
|
||||
*
|
||||
* Returns: (nullable)(transfer full): a #GcalEvent
|
||||
*/
|
||||
GcalEvent*
|
||||
gcal_manager_get_event_from_shell_search (GcalManager *self,
|
||||
const gchar *uuid)
|
||||
{
|
||||
GcalEvent *new_event;
|
||||
GList *l;
|
||||
time_t range_start, range_end;
|
||||
GatherEventData data = {
|
||||
.manager = self,
|
||||
.events = NULL,
|
||||
};
|
||||
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
g_return_val_if_fail (GCAL_IS_MANAGER (self), NULL);
|
||||
|
||||
new_event = NULL;
|
||||
|
||||
e_cal_data_model_get_subscriber_range (self->shell_search_data_model,
|
||||
self->search_view_data->subscriber,
|
||||
&range_start,
|
||||
&range_end);
|
||||
|
||||
e_cal_data_model_foreach_component (self->shell_search_data_model,
|
||||
range_start,
|
||||
range_end,
|
||||
gather_events,
|
||||
&data);
|
||||
|
||||
for (l = data.events; l != NULL; l = g_list_next (l))
|
||||
{
|
||||
GcalEvent *event;
|
||||
|
||||
event = l->data;
|
||||
|
||||
/* Found the event */
|
||||
if (g_strcmp0 (gcal_event_get_uid (event), uuid) == 0)
|
||||
new_event = event;
|
||||
else
|
||||
g_object_unref (event);
|
||||
}
|
||||
|
||||
g_list_free (data.events);
|
||||
|
||||
GCAL_RETURN (new_event);
|
||||
}
|
||||
|
||||
/**
|
||||
* gcal_manager_get_synchronizing:
|
||||
* @self: a #GcalManager
|
||||
|
||||
@@ -48,11 +48,6 @@ void gcal_manager_set_subscriber (GcalManager
|
||||
time_t range_start,
|
||||
time_t range_end);
|
||||
|
||||
void gcal_manager_set_search_subscriber (GcalManager *self,
|
||||
ECalDataModelSubscriber *subscriber,
|
||||
time_t range_start,
|
||||
time_t range_end);
|
||||
|
||||
void gcal_manager_set_query (GcalManager *self,
|
||||
const gchar *query);
|
||||
|
||||
@@ -89,25 +84,6 @@ GPtrArray* gcal_manager_get_events (GcalManager
|
||||
GDateTime *range_start,
|
||||
GDateTime *range_end);
|
||||
|
||||
/* GNOME Shell-related functions */
|
||||
GcalEvent* gcal_manager_get_event_from_shell_search (GcalManager *self,
|
||||
const gchar *uuid);
|
||||
|
||||
void gcal_manager_setup_shell_search (GcalManager *self,
|
||||
ECalDataModelSubscriber *subscriber);
|
||||
|
||||
void gcal_manager_set_shell_search_query (GcalManager *self,
|
||||
const gchar *query);
|
||||
|
||||
void gcal_manager_set_shell_search_subscriber (GcalManager *self,
|
||||
ECalDataModelSubscriber *subscriber,
|
||||
time_t range_start,
|
||||
time_t range_end);
|
||||
|
||||
gboolean gcal_manager_shell_search_done (GcalManager *self);
|
||||
|
||||
GList* gcal_manager_get_shell_search_events (GcalManager *self);
|
||||
|
||||
gboolean gcal_manager_get_synchronizing (GcalManager *self);
|
||||
|
||||
void gcal_manager_startup (GcalManager *self);
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "gcal-application.h"
|
||||
#include "gcal-debug.h"
|
||||
#include "gcal-event.h"
|
||||
#include "gcal-timeline.h"
|
||||
#include "gcal-timeline-subscriber.h"
|
||||
#include "gcal-window.h"
|
||||
#include "gcal-utils.h"
|
||||
|
||||
@@ -42,12 +44,17 @@ struct _GcalShellSearchProvider
|
||||
|
||||
PendingSearch *pending_search;
|
||||
GHashTable *events;
|
||||
|
||||
GDateTime *range_start;
|
||||
GDateTime *range_end;
|
||||
GcalTimeline *timeline;
|
||||
};
|
||||
|
||||
static void gcal_subscriber_interface_init (ECalDataModelSubscriberInterface *iface);
|
||||
static void gcal_timeline_subscriber_interface_init (GcalTimelineSubscriberInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GcalShellSearchProvider, gcal_shell_search_provider, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (E_TYPE_CAL_DATA_MODEL_SUBSCRIBER, gcal_subscriber_interface_init));
|
||||
G_IMPLEMENT_INTERFACE (GCAL_TYPE_TIMELINE_SUBSCRIBER,
|
||||
gcal_timeline_subscriber_interface_init));
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -71,48 +78,65 @@ sort_event_data (GcalEvent *a,
|
||||
return gcal_event_compare_with_current (a, b, GPOINTER_TO_INT (user_data));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
execute_search (GcalShellSearchProvider *self)
|
||||
static void
|
||||
maybe_update_range (GcalShellSearchProvider *self)
|
||||
{
|
||||
g_autoptr (GDateTime) start = NULL;
|
||||
g_autoptr (GDateTime) end = NULL;
|
||||
g_autoptr (GDateTime) now = NULL;
|
||||
gboolean range_changed = FALSE;
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
now = g_date_time_new_now (gcal_context_get_timezone (self->context));
|
||||
start = g_date_time_add_weeks (now, -1);
|
||||
end = g_date_time_add_weeks (now, 3);
|
||||
|
||||
if (self->range_start && gcal_date_time_compare_date (self->range_start, start) != 0)
|
||||
{
|
||||
gcal_set_date_time (&self->range_start, start);
|
||||
range_changed = TRUE;
|
||||
}
|
||||
|
||||
if (self->range_end && gcal_date_time_compare_date (self->range_end, end) != 0)
|
||||
{
|
||||
gcal_set_date_time (&self->range_end, end);
|
||||
range_changed = TRUE;
|
||||
}
|
||||
|
||||
if (range_changed)
|
||||
gcal_timeline_subscriber_range_changed (GCAL_TIMELINE_SUBSCRIBER (self));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
execute_search (GcalShellSearchProvider *self)
|
||||
{
|
||||
g_autofree gchar *search_query = NULL;
|
||||
GcalManager *manager;
|
||||
time_t range_start, range_end;
|
||||
guint i;
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
manager = gcal_context_get_manager (self->context);
|
||||
|
||||
now = g_date_time_new_now (gcal_context_get_timezone (self->context));
|
||||
start = g_date_time_add_weeks (now, -1);
|
||||
range_start = g_date_time_to_unix (start);
|
||||
|
||||
end = g_date_time_add_weeks (now, 3);
|
||||
range_end = g_date_time_to_unix (end);
|
||||
|
||||
gcal_manager_set_shell_search_subscriber (manager,
|
||||
E_CAL_DATA_MODEL_SUBSCRIBER (self),
|
||||
range_start, range_end);
|
||||
maybe_update_range (self);
|
||||
|
||||
search_query = g_strdup_printf ("(or (contains? \"summary\" \"%s\") (contains? \"description\" \"%s\"))",
|
||||
self->pending_search->terms[0], self->pending_search->terms[0]);
|
||||
self->pending_search->terms[0],
|
||||
self->pending_search->terms[0]);
|
||||
|
||||
for (i = 1; i < g_strv_length (self->pending_search->terms); i++)
|
||||
{
|
||||
g_autofree gchar *complete_query = NULL;
|
||||
g_autofree gchar *second_query = NULL;
|
||||
|
||||
second_query = g_strdup_printf ("(or (contains? \"summary\" \"%s\") (contains? \"description\" \"%s\"))",
|
||||
self->pending_search->terms[0], self->pending_search->terms[0]);
|
||||
self->pending_search->terms[0],
|
||||
self->pending_search->terms[0]);
|
||||
complete_query = g_strdup_printf ("(and %s %s)", search_query, second_query);
|
||||
|
||||
g_clear_pointer (&search_query, g_free);
|
||||
search_query = g_steal_pointer (&complete_query);
|
||||
}
|
||||
|
||||
gcal_manager_set_shell_search_query (manager, search_query);
|
||||
gcal_timeline_set_filter (self->timeline, search_query);
|
||||
g_application_hold (g_application_get_default ());
|
||||
|
||||
GCAL_RETURN (FALSE);
|
||||
@@ -240,15 +264,13 @@ activate_result_cb (GcalShellSearchProvider *self,
|
||||
{
|
||||
g_autoptr (GcalEvent) event = NULL;
|
||||
GApplication *application;
|
||||
GcalManager *manager;
|
||||
GDateTime *dtstart;
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
application = g_application_get_default ();
|
||||
|
||||
manager = gcal_context_get_manager (self->context);
|
||||
event = gcal_manager_get_event_from_shell_search (manager, result);
|
||||
event = g_hash_table_lookup (self->events, result);
|
||||
dtstart = gcal_event_get_date_start (event);
|
||||
|
||||
gcal_application_set_uuid (GCAL_APPLICATION (application), result);
|
||||
@@ -283,20 +305,23 @@ launch_search_cb (GcalShellSearchProvider *self,
|
||||
GCAL_RETURN (TRUE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
query_completed_cb (GcalShellSearchProvider *self,
|
||||
GcalManager *manager)
|
||||
static void
|
||||
on_timeline_completed_cb (GcalTimeline *timeline,
|
||||
GParamSpec *pspec,
|
||||
GcalShellSearchProvider *self)
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
GList *events, *l;
|
||||
g_autoptr (GList) events = NULL;
|
||||
GList *l;
|
||||
time_t current_time_t;
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
g_hash_table_remove_all (self->events);
|
||||
if (!gcal_timeline_is_complete (timeline))
|
||||
GCAL_RETURN ();
|
||||
|
||||
events = gcal_manager_get_shell_search_events (manager);
|
||||
if (events == NULL)
|
||||
events = g_hash_table_get_values (self->events);
|
||||
if (!events)
|
||||
{
|
||||
g_dbus_method_invocation_return_value (self->pending_search->invocation, g_variant_new ("(as)", NULL));
|
||||
GCAL_GOTO (out);
|
||||
@@ -319,7 +344,6 @@ query_completed_cb (GcalShellSearchProvider *self,
|
||||
|
||||
g_hash_table_insert (self->events, g_strdup (uid), l->data);
|
||||
}
|
||||
g_list_free (events);
|
||||
|
||||
g_dbus_method_invocation_return_value (self->pending_search->invocation, g_variant_new ("(as)", &builder));
|
||||
|
||||
@@ -329,51 +353,95 @@ out:
|
||||
g_clear_pointer (&self->pending_search, g_free);
|
||||
g_application_release (g_application_get_default ());
|
||||
|
||||
GCAL_RETURN (FALSE);
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
on_manager_calendar_added_cb (GcalManager *manager,
|
||||
GcalCalendar *calendar,
|
||||
GcalShellSearchProvider *self)
|
||||
{
|
||||
GCAL_ENTRY;
|
||||
|
||||
gcal_timeline_add_calendar (self->timeline, calendar);
|
||||
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
on_manager_calendar_removed_cb (GcalManager *manager,
|
||||
GcalCalendar *calendar,
|
||||
GcalShellSearchProvider *self)
|
||||
{
|
||||
GCAL_ENTRY;
|
||||
|
||||
gcal_timeline_remove_calendar (self->timeline, calendar);
|
||||
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
/*
|
||||
* ECalDataModelSubscriber iface
|
||||
* GcalTimelineSubscriber iface
|
||||
*/
|
||||
|
||||
static void
|
||||
gcal_shell_search_provider_component_changed (ECalDataModelSubscriber *subscriber,
|
||||
ECalClient *client,
|
||||
ECalComponent *comp)
|
||||
static GDateTime*
|
||||
gcal_shell_search_provider_get_range_start (GcalTimelineSubscriber *subscriber)
|
||||
{
|
||||
;
|
||||
GcalShellSearchProvider *self = GCAL_SHELL_SEARCH_PROVIDER (subscriber);
|
||||
|
||||
return g_date_time_ref (self->range_start);
|
||||
}
|
||||
|
||||
static GDateTime*
|
||||
gcal_shell_search_provider_get_range_end (GcalTimelineSubscriber *subscriber)
|
||||
{
|
||||
GcalShellSearchProvider *self = GCAL_SHELL_SEARCH_PROVIDER (subscriber);
|
||||
|
||||
return g_date_time_ref (self->range_end);
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_shell_search_provider_component_removed (ECalDataModelSubscriber *subscriber,
|
||||
ECalClient *client,
|
||||
const gchar *uid,
|
||||
const gchar *rid)
|
||||
gcal_shell_search_provider_add_event (GcalTimelineSubscriber *subscriber,
|
||||
GcalEvent *event)
|
||||
{
|
||||
;
|
||||
GcalShellSearchProvider *self = GCAL_SHELL_SEARCH_PROVIDER (subscriber);
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
g_hash_table_insert (self->events,
|
||||
g_strdup (gcal_event_get_uid (event)),
|
||||
g_object_ref (event));
|
||||
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_shell_search_provider_freeze (ECalDataModelSubscriber *subscriber)
|
||||
gcal_shell_search_provider_update_event (GcalTimelineSubscriber *subscriber,
|
||||
GcalEvent *event)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_shell_search_provider_thaw (ECalDataModelSubscriber *subscriber)
|
||||
gcal_shell_search_provider_remove_event (GcalTimelineSubscriber *subscriber,
|
||||
GcalEvent *event)
|
||||
{
|
||||
;
|
||||
GcalShellSearchProvider *self = GCAL_SHELL_SEARCH_PROVIDER (subscriber);
|
||||
|
||||
GCAL_ENTRY;
|
||||
|
||||
g_hash_table_remove (self->events, gcal_event_get_uid (event));
|
||||
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
gcal_subscriber_interface_init (ECalDataModelSubscriberInterface *iface)
|
||||
gcal_timeline_subscriber_interface_init (GcalTimelineSubscriberInterface *iface)
|
||||
{
|
||||
iface->component_added = gcal_shell_search_provider_component_changed;
|
||||
iface->component_modified = gcal_shell_search_provider_component_changed;
|
||||
iface->component_removed = gcal_shell_search_provider_component_removed;
|
||||
iface->freeze = gcal_shell_search_provider_freeze;
|
||||
iface->thaw = gcal_shell_search_provider_thaw;
|
||||
iface->get_range_start = gcal_shell_search_provider_get_range_start;
|
||||
iface->get_range_end = gcal_shell_search_provider_get_range_end;
|
||||
iface->add_event = gcal_shell_search_provider_add_event;
|
||||
iface->update_event = gcal_shell_search_provider_update_event;
|
||||
iface->remove_event = gcal_shell_search_provider_remove_event;
|
||||
}
|
||||
|
||||
|
||||
@@ -423,15 +491,21 @@ gcal_shell_search_provider_set_property (GObject *object,
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
if (g_set_object (&self->context, g_value_get_object (value)))
|
||||
{
|
||||
GcalManager *manager = gcal_context_get_manager (self->context);
|
||||
{
|
||||
GcalManager *manager;
|
||||
|
||||
gcal_manager_setup_shell_search (manager, E_CAL_DATA_MODEL_SUBSCRIBER (self));
|
||||
g_signal_connect_object (manager, "query-completed", G_CALLBACK (query_completed_cb), self, G_CONNECT_SWAPPED);
|
||||
g_assert (self->context == NULL);
|
||||
self->context = g_value_get_object (value);
|
||||
|
||||
g_object_notify_by_pspec (object, properties[PROP_CONTEXT]);
|
||||
}
|
||||
self->timeline = gcal_timeline_new (self->context);
|
||||
g_signal_connect (self->timeline, "notify::complete", G_CALLBACK (on_timeline_completed_cb), self);
|
||||
|
||||
manager = gcal_context_get_manager (self->context);
|
||||
g_signal_connect (manager, "calendar-added", G_CALLBACK (on_manager_calendar_added_cb), self);
|
||||
g_signal_connect (manager, "calendar-removed", G_CALLBACK (on_manager_calendar_removed_cb), self);
|
||||
|
||||
g_object_notify_by_pspec (object, properties[PROP_CONTEXT]);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -452,7 +526,7 @@ gcal_shell_search_provider_class_init (GcalShellSearchProviderClass *klass)
|
||||
"The context object",
|
||||
"The context object",
|
||||
GCAL_TYPE_CONTEXT,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,8 @@ struct _GcalTimeline
|
||||
gchar *filter;
|
||||
|
||||
GHashTable *calendars; /* GcalCalendar* -> GcalCalendarMonitor* */
|
||||
gint completed_calendars;
|
||||
|
||||
GHashTable *subscribers; /* GcalTimelineSubscriber* -> SubscriberData* */
|
||||
GcalRangeTree *subscriber_ranges;
|
||||
|
||||
@@ -63,6 +65,7 @@ G_DEFINE_TYPE (GcalTimeline, gcal_timeline, G_TYPE_OBJECT)
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_COMPLETE,
|
||||
PROP_CONTEXT,
|
||||
PROP_FILTER,
|
||||
N_PROPS
|
||||
@@ -75,6 +78,33 @@ static GParamSpec *properties [N_PROPS] = { NULL, };
|
||||
* Auxiliary methods
|
||||
*/
|
||||
|
||||
static inline gboolean
|
||||
is_timeline_complete (GcalTimeline *self)
|
||||
{
|
||||
return self->completed_calendars == g_hash_table_size (self->calendars);
|
||||
}
|
||||
|
||||
static void
|
||||
reset_completed_calendars (GcalTimeline *self)
|
||||
{
|
||||
gboolean was_complete = is_timeline_complete (self);
|
||||
|
||||
self->completed_calendars = 0;
|
||||
if (is_timeline_complete (self) != was_complete)
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COMPLETE]);
|
||||
}
|
||||
|
||||
static void
|
||||
increase_completed_calendars (GcalTimeline *self)
|
||||
{
|
||||
self->completed_calendars++;
|
||||
|
||||
g_assert (self->completed_calendars <= g_hash_table_size (self->calendars));
|
||||
|
||||
if (is_timeline_complete (self))
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COMPLETE]);
|
||||
}
|
||||
|
||||
static SubscriberData*
|
||||
subscriber_data_new (GcalTimelineSubscriber *subscriber)
|
||||
{
|
||||
@@ -226,6 +256,8 @@ update_range (GcalTimeline *self)
|
||||
{
|
||||
GcalCalendarMonitor *monitor;
|
||||
|
||||
reset_completed_calendars (self);
|
||||
|
||||
g_hash_table_iter_init (&iter, self->calendars);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &monitor))
|
||||
gcal_calendar_monitor_set_range (monitor, self->range_start, self->range_end);
|
||||
@@ -357,6 +389,8 @@ update_calendar_monitor_filters (GcalTimeline *self)
|
||||
GcalCalendarMonitor *monitor;
|
||||
GHashTableIter iter;
|
||||
|
||||
reset_completed_calendars (self);
|
||||
|
||||
g_hash_table_iter_init (&iter, self->calendars);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &monitor))
|
||||
gcal_calendar_monitor_set_filter (monitor, self->filter);
|
||||
@@ -473,6 +507,17 @@ on_calendar_monitor_event_removed_cb (GcalCalendarMonitor *monitor,
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static void
|
||||
on_calendar_monitor_completed_cb (GcalCalendarMonitor *monitor,
|
||||
GcalTimeline *self)
|
||||
{
|
||||
GCAL_ENTRY;
|
||||
|
||||
increase_completed_calendars (self);
|
||||
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_timeline_range_in_idle_cb (gpointer user_data)
|
||||
{
|
||||
@@ -538,6 +583,10 @@ gcal_timeline_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_COMPLETE:
|
||||
g_value_set_boolean (value, is_timeline_complete (self));
|
||||
break;
|
||||
|
||||
case PROP_CONTEXT:
|
||||
g_value_set_object (value, self->context);
|
||||
break;
|
||||
@@ -584,6 +633,17 @@ gcal_timeline_class_init (GcalTimelineClass *klass)
|
||||
object_class->get_property = gcal_timeline_get_property;
|
||||
object_class->set_property = gcal_timeline_set_property;
|
||||
|
||||
/**
|
||||
* GcalTimeline::complete:
|
||||
*
|
||||
* Whether all calendars in this timeline are completed.
|
||||
*/
|
||||
properties[PROP_COMPLETE] = g_param_spec_boolean ("complete",
|
||||
"Complete",
|
||||
"Complete",
|
||||
FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GcalSearchEngine::context:
|
||||
*
|
||||
@@ -664,6 +724,7 @@ gcal_timeline_add_calendar (GcalTimeline *self,
|
||||
g_signal_connect (monitor, "event-added", G_CALLBACK (on_calendar_monitor_event_added_cb), self);
|
||||
g_signal_connect (monitor, "event-updated", G_CALLBACK (on_calendar_monitor_event_updated_cb), self);
|
||||
g_signal_connect (monitor, "event-removed", G_CALLBACK (on_calendar_monitor_event_removed_cb), self);
|
||||
g_signal_connect (monitor, "completed", G_CALLBACK (on_calendar_monitor_completed_cb), self);
|
||||
g_hash_table_insert (self->calendars, calendar, g_object_ref (monitor));
|
||||
|
||||
if (self->range_start && self->range_end)
|
||||
@@ -789,3 +850,11 @@ gcal_timeline_set_filter (GcalTimeline *self,
|
||||
|
||||
GCAL_EXIT;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gcal_timeline_is_complete (GcalTimeline *self)
|
||||
{
|
||||
g_return_val_if_fail (GCAL_IS_TIMELINE (self), FALSE);
|
||||
|
||||
return is_timeline_complete (self);
|
||||
}
|
||||
|
||||
@@ -52,4 +52,6 @@ const gchar* gcal_timeline_get_filter (GcalTimeline
|
||||
void gcal_timeline_set_filter (GcalTimeline *self,
|
||||
const gchar *filter);
|
||||
|
||||
gboolean gcal_timeline_is_complete (GcalTimeline *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
Reference in New Issue
Block a user