diff --git a/src/gcal-manager.c b/src/gcal-manager.c index 2e8b7955..caba7ea3 100644 --- a/src/gcal-manager.c +++ b/src/gcal-manager.c @@ -38,70 +38,70 @@ typedef struct { - GcalEvent *event; - GcalManager *manager; + GcalEvent *event; + GcalManager *manager; } AsyncOpsData; typedef struct { ECalDataModelSubscriber *subscriber; - gchar *query; + gchar *query; - guint sources_left; - gboolean passed_start; - gboolean search_done; + guint sources_left; + gboolean passed_start; + gboolean search_done; } ViewStateData; typedef struct { - ECalClient *client; - gboolean connected; + ECalClient *client; + gboolean connected; } GcalManagerUnit; typedef struct { - gchar *event_uid; - GcalManagerUnit *unit; - GcalManagerUnit *new_unit; - ECalComponent *new_component; - GcalManager *manager; + gchar *event_uid; + GcalManagerUnit *unit; + GcalManagerUnit *new_unit; + ECalComponent *new_component; + GcalManager *manager; } MoveEventData; struct _GcalManager { - GObject parent; + GObject parent; /** * The list of clients we are managing. * Each value is of type GCalStoreUnit * And each key is the source uid */ - GHashTable *clients; + GHashTable *clients; - ESourceRegistry *source_registry; + ESourceRegistry *source_registry; ECredentialsPrompter *credentials_prompter; - ECalDataModel *e_data_model; - ECalDataModel *search_data_model; + ECalDataModel *e_data_model; + ECalDataModel *search_data_model; - ECalDataModel *shell_search_data_model; - ViewStateData *search_view_data; + ECalDataModel *shell_search_data_model; + ViewStateData *search_view_data; - GCancellable *async_ops; + GCancellable *async_ops; - GoaClient *goa_client; + GoaClient *goa_client; - GcalClock *clock; + GcalClock *clock; /* state flags */ - gboolean goa_client_ready; - gint sources_at_launch; + gboolean goa_client_ready; + gint sources_at_launch; /* timezone */ - icaltimezone *system_timezone; + icaltimezone *system_timezone; /* property */ - GSettings *settings; + GSettings *settings; }; G_DEFINE_TYPE (GcalManager, gcal_manager, G_TYPE_OBJECT) @@ -131,12 +131,12 @@ static GParamSpec *properties[NUM_PROPS] = { NULL, }; /* -- start: threading related code provided by Milan Crha */ typedef struct { - EThreadJobFunc func; - gpointer user_data; - GDestroyNotify free_user_data; + EThreadJobFunc func; + gpointer user_data; + GDestroyNotify free_user_data; - GCancellable *cancellable; - GError *error; + GCancellable *cancellable; + GError *error; } ThreadJobData; static void @@ -175,7 +175,7 @@ thread_job_thread (gpointer user_data) return g_thread_self (); } -static GCancellable * +static GCancellable* submit_thread_job (EThreadJobFunc func, gpointer user_data, GDestroyNotify free_user_data) diff --git a/src/gcal-search-view.c b/src/gcal-search-view.c index 45a208d8..219121c2 100644 --- a/src/gcal-search-view.c +++ b/src/gcal-search-view.c @@ -35,10 +35,10 @@ typedef struct struct _GcalSearchView { - GtkPopover parent; + GtkPopover parent; - GtkWidget *listbox; - GtkWidget *stack; + GtkWidget *listbox; + GtkWidget *stack; /* Since the user can have (literally) * thousands of events, the usage of @@ -46,23 +46,23 @@ struct _GcalSearchView * the RowEventData lookup constant * time. */ - GHashTable *uuid_to_event; + GHashTable *uuid_to_event; /* misc */ - gint no_results_timeout_id; - gint num_results; - gchar *field; - gchar *query; - time_t current_utc_date; - guint search_timeout_id; + gint no_results_timeout_id; + gint num_results; + gchar *field; + gchar *query; + time_t current_utc_date; + guint search_timeout_id; /* property */ - icaltimetype *date; - GcalManager *manager; /* weak reference */ + icaltimetype *date; + GcalManager *manager; /* weak reference */ /* flags */ - gboolean format_24h; - gboolean subscribed; + gboolean format_24h; + gboolean subscribed; }; enum diff --git a/src/gcal-timer.c b/src/gcal-timer.c index 66fd56c4..abba7770 100644 --- a/src/gcal-timer.c +++ b/src/gcal-timer.c @@ -31,9 +31,9 @@ */ typedef struct _GcalTimer { - GSource parent; - gint64 last_event; - gint64 default_duration; + GSource parent; + gint64 last_event; + gint64 default_duration; } GcalTimer; @@ -48,25 +48,24 @@ typedef struct _GcalTimer */ typedef struct { - GcalTimer *timer; /* unowned */ - GCalTimerFunc callback; - GDestroyNotify destroy_notify; - gpointer data; + GcalTimer *timer; /* unowned */ + GCalTimerFunc callback; + GDestroyNotify destroy_notify; + gpointer data; } CbWrapperData; -static void timer_func_destroy_notify_wrapper (CbWrapperData *wrapper); +static void timer_func_destroy_notify_wrapper (CbWrapperData *wrapper); -static gboolean timer_func_wrapper (CbWrapperData *wrapper); +static gboolean timer_func_wrapper (CbWrapperData *wrapper); -static gboolean timer_source_dispatch (GcalTimer *self, - GSourceFunc callback, - CbWrapperData *user_data); +static gboolean timer_source_dispatch (GcalTimer *self, + GSourceFunc callback, + CbWrapperData *user_data); -static void schedule_next (GcalTimer *self); - -static void timer_source_finalize (GcalTimer *self); +static void schedule_next (GcalTimer *self); +static void timer_source_finalize (GcalTimer *self); @@ -82,8 +81,6 @@ timer_func_destroy_notify_wrapper (CbWrapperData *wrapper) g_free (wrapper); } - - static gboolean timer_func_wrapper (CbWrapperData *wrapper) { @@ -95,8 +92,6 @@ timer_func_wrapper (CbWrapperData *wrapper) return G_SOURCE_CONTINUE; } - - static gboolean timer_source_dispatch (GcalTimer *self, GSourceFunc user_callback, @@ -115,8 +110,6 @@ timer_source_dispatch (GcalTimer *self, return result; } - - static void schedule_next (GcalTimer *self) { @@ -135,8 +128,6 @@ schedule_next (GcalTimer *self) g_source_set_ready_time ((GSource*) self, 0); } - - static void timer_source_finalize (GcalTimer *self) { @@ -182,8 +173,6 @@ gcal_timer_new (gint64 default_duration) return g_steal_pointer (&self); } - - /** * gcal_timer_set_start: * @self: The #GcalTimer. @@ -200,8 +189,6 @@ gcal_timer_start (GcalTimer *self) schedule_next (self); } - - /** * gcal_timer_set_reset: * @self: The #GcalTimer. @@ -218,8 +205,6 @@ gcal_timer_reset (GcalTimer *self) schedule_next (self); } - - /** * gcal_timer_set_stop: * @self: The #GcalTimer. @@ -235,8 +220,6 @@ gcal_timer_stop (GcalTimer *self) g_source_set_ready_time ((GSource*) self, -1); } - - /** * gcal_timer_is_running * @self: The #GcalTimer. @@ -251,8 +234,6 @@ gcal_timer_is_running (GcalTimer *self) return g_source_get_ready_time ((GSource*) self) >= 0; } - - /** * gcal_timer_set_duration: * @self: The #GcalTimer. @@ -280,8 +261,6 @@ gcal_timer_set_default_duration (GcalTimer *self, schedule_next (self); } - - /** * gcal_timer_get_default_duration: * @self: The #GcalTimer. @@ -296,7 +275,6 @@ gcal_timer_get_default_duration (GcalTimer *self) return self->default_duration; } - /** * gcal_timer_set_callback: * @self: The #GcalTimer. @@ -330,7 +308,6 @@ gcal_timer_set_callback (GcalTimer *self, (GDestroyNotify) timer_func_destroy_notify_wrapper); } - /** * gcal_timer_free: * @self: The #GcalTimer. diff --git a/src/gcal-timer.h b/src/gcal-timer.h index 322d616f..8caabe28 100644 --- a/src/gcal-timer.h +++ b/src/gcal-timer.h @@ -28,27 +28,27 @@ typedef struct _GcalTimer GcalTimer; typedef void (*GCalTimerFunc) (GcalTimer *self, gpointer data); -GcalTimer* gcal_timer_new (gint64 default_duration); +GcalTimer* gcal_timer_new (gint64 default_duration); -void gcal_timer_start (GcalTimer *self); +void gcal_timer_start (GcalTimer *self); -void gcal_timer_reset (GcalTimer *self); +void gcal_timer_reset (GcalTimer *self); -void gcal_timer_stop (GcalTimer *self); +void gcal_timer_stop (GcalTimer *self); -gboolean gcal_timer_is_running (GcalTimer *self); +gboolean gcal_timer_is_running (GcalTimer *self); -void gcal_timer_set_default_duration (GcalTimer *self, - gint64 duration); +void gcal_timer_set_default_duration (GcalTimer *self, + gint64 duration); -gint64 gcal_timer_get_default_duration (GcalTimer *self); +gint64 gcal_timer_get_default_duration (GcalTimer *self); -void gcal_timer_set_callback (GcalTimer *self, - GCalTimerFunc func, - gpointer data, - GDestroyNotify notify); +void gcal_timer_set_callback (GcalTimer *self, + GCalTimerFunc func, + gpointer data, + GDestroyNotify notify); -void gcal_timer_free (GcalTimer *self); +void gcal_timer_free (GcalTimer *self); #endif /* __GCAL_TIMER_H__ */ diff --git a/src/gcal-utils.h b/src/gcal-utils.h index 2b2675ac..a7b19561 100644 --- a/src/gcal-utils.h +++ b/src/gcal-utils.h @@ -70,99 +70,100 @@ typedef enum GCAL_WEEK_DAY_SATURDAY = 1 << 6 } GcalWeekDay; -GType icaltime_get_type (void) G_GNUC_CONST; +GType icaltime_get_type (void) G_GNUC_CONST; -gint datetime_compare_date (GDateTime *dt1, - GDateTime *dt2); +gint datetime_compare_date (GDateTime *dt1, + GDateTime *dt2); -icaltimetype* datetime_to_icaltime (GDateTime *dt); +icaltimetype* datetime_to_icaltime (GDateTime *dt); -gboolean datetime_is_date (GDateTime *dt); +gboolean datetime_is_date (GDateTime *dt); -GDateTime* icaltime_to_datetime (const icaltimetype *date); +GDateTime* icaltime_to_datetime (const icaltimetype *date); -icaltimetype* gcal_dup_icaltime (const icaltimetype *date); +icaltimetype* gcal_dup_icaltime (const icaltimetype *date); -gchar* gcal_get_weekday (gint i); +gchar* gcal_get_weekday (gint i); -gchar* gcal_get_month_name (gint i); +gchar* gcal_get_month_name (gint i); -cairo_surface_t*gcal_get_surface_from_color (GdkRGBA *color, - gint size); +cairo_surface_t* gcal_get_surface_from_color (GdkRGBA *color, + gint size); -cairo_surface_t*get_circle_surface_from_color (GdkRGBA *color, - gint size); +cairo_surface_t* get_circle_surface_from_color (GdkRGBA *color, + gint size); -void get_color_name_from_source (ESource *source, - GdkRGBA *out_color); +void get_color_name_from_source (ESource *source, + GdkRGBA *out_color); -gchar* get_desc_from_component (ECalComponent *component, - const gchar *joint_char); +gchar* get_desc_from_component (ECalComponent *component, + const gchar *joint_char); -gchar* get_uuid_from_component (ESource *source, - ECalComponent *component); +gchar* get_uuid_from_component (ESource *source, + ECalComponent *component); -gint get_first_weekday (void); +gint get_first_weekday (void); -ECalComponent* build_component_from_details (const gchar *summary, - GDateTime *initial_date, - GDateTime *final_date); +ECalComponent* build_component_from_details (const gchar *summary, + GDateTime *initial_date, + GDateTime *final_date); -gint icaltime_compare_date (const icaltimetype *date1, - const icaltimetype *date2); +gint icaltime_compare_date (const icaltimetype *date1, + const icaltimetype *date2); -gint icaltime_compare_with_current (const icaltimetype *date1, - const icaltimetype *date2, - time_t *current_time_t); +gint icaltime_compare_with_current (const icaltimetype *date1, + const icaltimetype *date2, + time_t *current_time_t); -GDateTime* get_start_of_week (icaltimetype *date); +GDateTime* get_start_of_week (icaltimetype *date); -GDateTime* get_end_of_week (icaltimetype *date); +GDateTime* get_end_of_week (icaltimetype *date); -gboolean is_clock_format_24h (void); +gboolean is_clock_format_24h (void); /* code brought from evolution */ -gsize e_strftime_fix_am_pm (gchar *str, - gsize max, - const gchar *fmt, - const struct tm *tm); -gsize e_utf8_strftime_fix_am_pm (gchar *str, +gsize e_strftime_fix_am_pm (gchar *str, + gsize max, + const gchar *fmt, + const struct tm *tm); - gsize max, - const gchar *fmt, - const struct tm *tm); +gsize e_utf8_strftime_fix_am_pm (gchar *str, + gsize max, + const gchar *fmt, + const struct tm *tm); -void fix_popover_menu_icons (GtkPopover *popover); +void fix_popover_menu_icons (GtkPopover *popover); -void get_source_parent_name_color (GcalManager *manager, - ESource *source, - gchar **name, - gchar **color); -gchar* format_utc_offset (gint64 offset); +void get_source_parent_name_color (GcalManager *manager, + ESource *source, + gchar **name, + gchar **color); -gint get_alarm_trigger_minutes (GcalEvent *event, - ECalComponentAlarm *alarm); +gchar* format_utc_offset (gint64 offset); -gboolean should_change_date_for_scroll (gdouble *scroll_value, - GdkEventScroll *scroll_event); +gint get_alarm_trigger_minutes (GcalEvent *event, + ECalComponentAlarm *alarm); -gboolean is_source_enabled (ESource *source); +gboolean should_change_date_for_scroll (gdouble *scroll_value, + GdkEventScroll *scroll_event); -gboolean ask_recurrence_modification_type (GtkWidget *parent, - GcalRecurrenceModType *modtype, - ESource *source); +gboolean is_source_enabled (ESource *source); -gboolean is_workday (guint day); +gboolean ask_recurrence_modification_type (GtkWidget *parent, + GcalRecurrenceModType *modtype, + ESource *source); -GList* filter_event_list_by_uid_and_modtype (GList *widgets, - GcalRecurrenceModType mod, - const gchar *uid); +gboolean is_workday (guint day); -gboolean gcal_translate_child_window_position (GtkWidget *target, - GdkWindow *child_window, - gdouble src_x, - gdouble src_y, - gdouble *real_x, - gdouble *real_y); +GList* filter_event_list_by_uid_and_modtype (GList *widgets, + GcalRecurrenceModType mod, + const gchar *uid); + +gboolean gcal_translate_child_window_position (GtkWidget *target, + GdkWindow *child_window, + gdouble src_x, + gdouble src_y, + gdouble *real_x, + gdouble *real_y); #endif /* __GCAL_UTILS_H__ */ diff --git a/src/gcal-weather-info.c b/src/gcal-weather-info.c index a85353a1..2c8ef9f0 100644 --- a/src/gcal-weather-info.c +++ b/src/gcal-weather-info.c @@ -21,15 +21,6 @@ #include #include "gcal-weather-info.h" -static void gcal_weather_info_set_date (GcalWeatherInfo *self, - GDate *date); - -static void gcal_weather_info_set_temperature (GcalWeatherInfo *self, - const gchar *temperature); - -static void gcal_weather_info_set_icon_name (GcalWeatherInfo *self, - const gchar *icon_name); - /* _GcalWeatherInfo: * @date: (not nullable): The day this information belongs to. @@ -51,6 +42,15 @@ struct _GcalWeatherInfo { }; +static void gcal_weather_info_set_date (GcalWeatherInfo *self, + GDate *date); + +static void gcal_weather_info_set_temperature (GcalWeatherInfo *self, + const gchar *temperature); + +static void gcal_weather_info_set_icon_name (GcalWeatherInfo *self, + const gchar *icon_name); + G_DEFINE_TYPE (GcalWeatherInfo, gcal_weather_info, G_TYPE_OBJECT) enum { @@ -79,8 +79,6 @@ gcal_weather_info_finalize (GObject *object) G_OBJECT_CLASS (gcal_weather_info_parent_class)->finalize (object); } - - static void gcal_weather_info_get_property (GObject *object, guint property_id, @@ -107,8 +105,6 @@ gcal_weather_info_get_property (GObject *object, } } - - static void gcal_weather_info_set_property (GObject *object, guint property_id, @@ -138,8 +134,6 @@ gcal_weather_info_set_property (GObject *object, } } - - static void gcal_weather_info_class_init (GcalWeatherInfoClass *klass) { @@ -185,8 +179,6 @@ gcal_weather_info_class_init (GcalWeatherInfoClass *klass) G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } - - static void gcal_weather_info_init (GcalWeatherInfo *self) { @@ -215,8 +207,6 @@ gcal_weather_info_set_date (GcalWeatherInfo *self, self->date = *date; } - - /* gcal_weather_info_set_temperature: * @self: A #GcalWeatherInfo instance. * @temperature: A weather string. @@ -238,9 +228,7 @@ gcal_weather_info_set_temperature (GcalWeatherInfo *self, } } - - -/* gcal_weather_info_set_icon_name: +/* gcal_weather_info_set_icon_name: * @self: A #GcalWeatherInfo instance. * @icon_name: The name of the icon to display. * @@ -262,6 +250,7 @@ gcal_weather_info_set_icon_name (GcalWeatherInfo *self, } + /* < public > */ /** @@ -293,8 +282,6 @@ gcal_weather_info_new (GDate *date, return info; } - - /** * gcal_weather_info_get_date: * @self: A #GcalWeatherInfo instance. @@ -311,8 +298,6 @@ gcal_weather_info_get_date (GcalWeatherInfo *self, *date = self->date; } - - /** * gcal_weather_info_get_icon_name: * @self: A #GcalWeatherInfo instance. @@ -327,8 +312,6 @@ gcal_weather_info_get_icon_name (GcalWeatherInfo *self) return self->icon_name; } - - /** * gcal_weather_info_get_temperature: * @self: A #GcalWeatherInfo instance. diff --git a/src/gcal-weather-info.h b/src/gcal-weather-info.h index d2e73447..35655e2e 100644 --- a/src/gcal-weather-info.h +++ b/src/gcal-weather-info.h @@ -30,19 +30,19 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (GcalWeatherInfo, gcal_weather_info, GCAL, WEATHER_INFO, GObject) -GcalWeatherInfo* gcal_weather_info_new (GDate *date, - const gchar *icon_name, - const gchar *temperature); +GcalWeatherInfo* gcal_weather_info_new (GDate *date, + const gchar *icon_name, + const gchar *temperature); -void gcal_weather_info_get_date (GcalWeatherInfo *self, - GDate *date); +void gcal_weather_info_get_date (GcalWeatherInfo *self, + GDate *date); -void gcal_weather_info_get_date (GcalWeatherInfo *self, - GDate *date); +void gcal_weather_info_get_date (GcalWeatherInfo *self, + GDate *date); -const gchar* gcal_weather_info_get_icon_name (GcalWeatherInfo *self); +const gchar* gcal_weather_info_get_icon_name (GcalWeatherInfo *self); -const gchar* gcal_weather_info_get_temperature (GcalWeatherInfo *self); +const gchar* gcal_weather_info_get_temperature (GcalWeatherInfo *self); G_END_DECLS diff --git a/src/gcal-weather-service.c b/src/gcal-weather-service.c index 6bc76fbc..aa39598c 100644 --- a/src/gcal-weather-service.c +++ b/src/gcal-weather-service.c @@ -37,8 +37,8 @@ G_BEGIN_DECLS */ typedef struct { - gchar *name; - gboolean night_support; + gchar *name; + gboolean night_support; } GcalWeatherIconInfo; @@ -73,37 +73,132 @@ typedef struct */ struct _GcalWeatherService { - GObjectClass parent; + GObjectClass parent; /* */ /* */ - GTimeZone *time_zone; /* owned, nullable */ + GTimeZone *time_zone; /* owned, nullable */ /* timer: */ - guint check_interval_new; - guint check_interval_renew; - GcalTimer *duration_timer; - GcalTimer *midnight_timer; + guint check_interval_new; + guint check_interval_renew; + GcalTimer *duration_timer; + GcalTimer *midnight_timer; /* network monitoring */ - gulong network_changed_sid; + gulong network_changed_sid; /* locations: */ - GClueSimple *location_service; /* owned, nullable */ - GCancellable *location_cancellable; /* owned, non-null */ - gboolean location_service_running; + GClueSimple *location_service; /* owned, nullable */ + GCancellable *location_cancellable; /* owned, non-null */ + gboolean location_service_running; /* weather: */ - GSList *weather_infos; /* owned[owned] */ - gint64 weather_infos_upated; - gint64 valid_timespan; - GWeatherInfo *gweather_info; /* owned, nullable */ - guint max_days; - gboolean weather_service_running; + GSList *weather_infos; /* owned[owned] */ + gint64 weather_infos_upated; + gint64 valid_timespan; + GWeatherInfo *gweather_info; /* owned, nullable */ + guint max_days; + gboolean weather_service_running; }; +/* Auxiliary methods: */ +static void on_network_change (GNetworkMonitor *monitor, + gboolean available, + GcalWeatherService *self); + +static void on_gclue_simple_creation (GClueSimple *source, + GAsyncResult *result, + GcalWeatherService *data); + +static void on_gclue_location_changed (GClueLocation *location, + GcalWeatherService *self); + +static void on_gclue_client_activity_changed (GClueClient *client, + GcalWeatherService *self); + +static void on_gclue_client_stop (GClueClient *client, + GAsyncResult *res, + GClueSimple *simple); + +static void on_gweather_update (GWeatherInfo *info, + GcalWeatherService *self); + +static void on_duration_timer_timeout (GcalTimer *timer, + GcalWeatherService *self); + +static void on_midnight_timer_timeout (GcalTimer *timer, + GcalWeatherService *self); + + +/* Timer Helpers: */ +static void update_timeout_interval (GcalWeatherService *self); + +static void schedule_midnight (GcalWeatherService *self); + +static void start_timer (GcalWeatherService *self); + +static void stop_timer (GcalWeatherService *self); + + +/* Internal location API and callbacks: */ + +static void update_location (GcalWeatherService *self, + GWeatherLocation *location); + +static void update_gclue_location (GcalWeatherService *self, + GClueLocation *location); + + +/* Internal Weather API */ +static void set_max_days (GcalWeatherService *self, + guint days); + +static void set_valid_timespan (GcalWeatherService *self, + gint64 timespan); + +static gboolean has_valid_weather_infos (GcalWeatherService *self); + +static void update_weather (GcalWeatherService *self, + GWeatherInfo *info, + gboolean reuse_old_on_error); + + +/* Internal weather update API and callbacks */ +static void set_check_interval_new (GcalWeatherService *self, + guint check_interval); + +static void set_check_interval_renew (GcalWeatherService *self, + guint check_interval); + +static gssize get_normalized_icon_name_len (const gchar *str); + +static gchar* get_normalized_icon_name (GWeatherInfo *gwi, + gboolean is_night_icon); + +static gint get_icon_name_sortkey (const gchar *icon_name, + gboolean *supports_night_icon); + +static gboolean get_time_day_start (GcalWeatherService *self, + GDate *ret_date, + gint64 *ret_unix, + gint64 *ret_unix_exact); + +static inline gboolean get_gweather_temperature (GWeatherInfo *gwi, + gdouble *temp); + +static gboolean compute_weather_info_data (GSList *samples, + gboolean is_today, + gchar **icon_name, + gchar **temperature); + +static GSList* preprocess_gweather_reports (GcalWeatherService *self, + GSList *samples); + + +G_DEFINE_TYPE (GcalWeatherService, gcal_weather_service, G_TYPE_OBJECT) enum { @@ -124,99 +219,6 @@ enum static guint gcal_weather_service_signals[SIG_NUM] = { 0 }; - -G_DEFINE_TYPE (GcalWeatherService, gcal_weather_service, G_TYPE_OBJECT) - - -/* Timer Helpers: */ -static void update_timeout_interval (GcalWeatherService *self); - -static void schedule_midnight (GcalWeatherService *self); - -static void start_timer (GcalWeatherService *self); - -static void stop_timer (GcalWeatherService *self); - -static void on_network_change (GNetworkMonitor *monitor, - gboolean available, - GcalWeatherService *self); - - -/* Internal location API and callbacks: */ -static void gcal_weather_service_update_location (GcalWeatherService *self, - GWeatherLocation *location); - -static void gcal_weather_service_update_gclue_location (GcalWeatherService *self, - GClueLocation *location); - -static void on_gclue_simple_creation (GClueSimple *source, - GAsyncResult *result, - GcalWeatherService *data); - -static void on_gclue_location_changed (GClueLocation *location, - GcalWeatherService *self); - -static void on_gclue_client_activity_changed (GClueClient *client, - GcalWeatherService *self); - -static void on_gclue_client_stop (GClueClient *client, - GAsyncResult *res, - GClueSimple *simple); - -/* Internal Weather API */ -static void gcal_weather_service_set_max_days (GcalWeatherService *self, - guint days); - -static void gcal_weather_service_set_valid_timespan (GcalWeatherService *self, - gint64 timespan); - -static gboolean has_valid_weather_infos (GcalWeatherService *self); - -static void gcal_weather_service_update_weather (GcalWeatherService *self, - GWeatherInfo *info, - gboolean reuse_old_on_error); - -static void on_gweather_update (GWeatherInfo *info, - GcalWeatherService *self); - -/* Internal weather update timer API and callbacks */ -static void gcal_weather_service_set_check_interval_new (GcalWeatherService *self, - guint check_interval); - -static void gcal_weather_service_set_check_interval_renew (GcalWeatherService *self, - guint check_interval); - -static gssize get_normalized_icon_name_len (const gchar *str); - -static gchar* get_normalized_icon_name (GWeatherInfo *gwi, - gboolean is_night_icon); - -static gint get_icon_name_sortkey (const gchar *icon_name, - gboolean *supports_night_icon); - -static void on_duration_timer_timeout (GcalTimer *timer, - GcalWeatherService *self); - -static void on_midnight_timer_timeout (GcalTimer *timer, - GcalWeatherService *self); - -static gboolean get_time_day_start (GcalWeatherService *self, - GDate *ret_date, - gint64 *ret_unix, - gint64 *ret_unix_exact); - -static inline gboolean get_gweather_temperature (GWeatherInfo *gwi, - gdouble *temp); - -static gboolean compute_weather_info_data (GSList *samples, - gboolean is_today, - gchar **icon_name, - gchar **temperature); - -static GSList* preprocess_gweather_reports (GcalWeatherService *self, - GSList *samples); - - G_END_DECLS @@ -265,8 +267,6 @@ gcal_weather_service_finalize (GObject *object) G_OBJECT_CLASS (gcal_weather_service_parent_class)->finalize (object); } - - static void gcal_weather_service_get_property (GObject *object, guint prop_id, @@ -299,8 +299,6 @@ gcal_weather_service_get_property (GObject *object, } } - - static void gcal_weather_service_set_property (GObject *object, guint prop_id, @@ -313,19 +311,19 @@ gcal_weather_service_set_property (GObject *object, switch (prop_id) { case PROP_MAX_DAYS: - gcal_weather_service_set_max_days (self, g_value_get_uint (value)); + set_max_days (self, g_value_get_uint (value)); break; case PROP_TIME_ZONE: gcal_weather_service_set_time_zone (self, g_value_get_pointer (value)); break; case PROP_CHECK_INTERVAL_NEW: - gcal_weather_service_set_check_interval_new (self, g_value_get_uint (value)); + set_check_interval_new (self, g_value_get_uint (value)); break; case PROP_CHECK_INTERVAL_RENEW: - gcal_weather_service_set_check_interval_renew (self, g_value_get_uint (value)); + set_check_interval_renew (self, g_value_get_uint (value)); break; case PROP_VALID_TIMESPAN: - gcal_weather_service_set_valid_timespan (self, g_value_get_int64 (value)); + set_valid_timespan (self, g_value_get_int64 (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -333,8 +331,6 @@ gcal_weather_service_set_property (GObject *object, } } - - static void gcal_weather_service_class_init (GcalWeatherServiceClass *klass) { @@ -428,8 +424,6 @@ gcal_weather_service_class_init (GcalWeatherServiceClass *klass) 0); } - - static void gcal_weather_service_init (GcalWeatherService *self) { @@ -459,46 +453,6 @@ gcal_weather_service_init (GcalWeatherService *self) self); } - - -/* drop_suffix: - * @str: A icon name to normalize. - * - * Translates a given weather icon name to the - * one to display for folded weather reports. - * - * Returns: Number of initial characters that - * belong to the normalized name. - */ -static gssize -get_normalized_icon_name_len (const gchar *str) -{ - const gchar suffix1[] = "-symbolic"; - const gssize suffix1_len = G_N_ELEMENTS (suffix1) - 1; - - const gchar suffix2[] = "-night"; - const gssize suffix2_len = G_N_ELEMENTS (suffix2) - 1; - - gssize clean_len; - gssize str_len; - - g_return_val_if_fail (str != NULL, -1); - - str_len = strlen (str); - - clean_len = str_len - suffix1_len; - if (clean_len >= 0 && memcmp (suffix1, str + clean_len, suffix1_len) == 0) - str_len = clean_len; - - clean_len = str_len - suffix2_len; - if (clean_len >= 0 && memcmp (suffix2, str + clean_len, suffix2_len) == 0) - str_len = clean_len; - - return str_len; -} - - - /* get_normalized_icon_name: * @str: A icon name to normalize. * @@ -556,6 +510,649 @@ get_normalized_icon_name (GWeatherInfo* wi, } +/************** + * < private > + **************/ + +/* + * Auxiliary methods: + */ + +/* on_network_change: + * @monitor: The emitting #GNetworkMonitor + * @available: The current value of “network-available” + * @self: The #GcalWeatherService instance. + * + * Starts and stops timer based on monitored network + * changes. + */ +static void +on_network_change (GNetworkMonitor *monitor, + gboolean available, + GcalWeatherService *self) +{ + gboolean is_running; + + g_return_if_fail (G_IS_NETWORK_MONITOR (monitor)); + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + + g_debug ("network changed, available = %d", available); + + is_running = gcal_timer_is_running (self->duration_timer); + if (available && !is_running) + { + if (self->gweather_info != NULL) + gweather_info_update (self->gweather_info); + + start_timer (self); + } + else if (!available && is_running) + { + stop_timer (self); + } +} + +/* on_gclue_simple_creation: + * @source: + * @result: Result of gclue_simple_new(). + * @self: (transfer full): A GcalWeatherService reference. + * + * Callback used in gcal_weather_service_run(). + */ +static void +on_gclue_simple_creation (GClueSimple *_source, + GAsyncResult *result, + GcalWeatherService *self) +{ + GClueSimple *location_service; /* owned */ + GClueLocation *location; /* unowned */ + GClueClient *client; /* unowned */ + g_autoptr (GError) error = NULL; + + g_return_if_fail (G_IS_ASYNC_RESULT (result)); + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + + /* make sure we do not touch self->location_service + * if the current operation was cancelled. + */ + location_service = gclue_simple_new_finish (result, &error); + if (error != NULL) + { + g_assert (location_service == NULL); + + if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_CANCELLED) + /* Cancelled during creation. Silently fail. */; + else + g_warning ("Could not create GCLueSimple: %s", error->message); + + g_object_unref (self); + return; + } + + g_assert (self->location_service == NULL); + g_assert (location_service != NULL); + + self->location_service = g_steal_pointer (&location_service); + + location = gclue_simple_get_location (self->location_service); + client = gclue_simple_get_client (self->location_service); + + if (location != NULL) + { + update_gclue_location (self, location); + + g_signal_connect_object (location, + "notify::location", + G_CALLBACK (on_gclue_location_changed), + self, + 0); + } + + g_signal_connect_object (client, + "notify::active", + G_CALLBACK (on_gclue_client_activity_changed), + self, + 0); + + g_object_unref (self); +} + +/* on_gclue_location_changed: + * @location: #GClueLocation owned by @self + * @self: The #GcalWeatherService + * + * Handles location changes. + */ +static void +on_gclue_location_changed (GClueLocation *location, + GcalWeatherService *self) +{ + g_return_if_fail (GCLUE_IS_LOCATION (location)); + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + + update_gclue_location (self, location); +} + +/* on_gclue_client_activity_changed: + * @client: The #GClueclient ownd by @self + * @self: The #GcalWeatherService + * + * Handles location client activity changes. + */ +static void +on_gclue_client_activity_changed (GClueClient *client, + GcalWeatherService *self) +{ + g_return_if_fail (GCLUE_IS_CLIENT (client)); + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + + /* Notify listeners about unknown locations: */ + update_location (self, NULL); +} + +/* on_gclue_client_stop: + * @source_object: A #GClueClient. + * @res: Result of gclue_client_call_stop(). + * @simple: (transfer full): A #GClueSimple. + * + * Helper-callback used in gcal_weather_service_stop(). + */ +static void +on_gclue_client_stop (GClueClient *client, + GAsyncResult *res, + GClueSimple *simple) +{ + g_autoptr(GError) error = NULL; /* owned */ + gboolean stopped; + + g_return_if_fail (GCLUE_IS_CLIENT (client)); + g_return_if_fail (G_IS_ASYNC_RESULT (res)); + g_return_if_fail (GCLUE_IS_SIMPLE (simple)); + + stopped = gclue_client_call_stop_finish (client, + res, + &error); + if (error != NULL) + g_warning ("Could not stop location service: %s", error->message); + else if (!stopped) + g_warning ("Could not stop location service"); + + g_object_unref (simple); +} + +/* on_gweather_update: + * @self: A #GcalWeatherService instance. + * @timespan: Amount of seconds we consider weather information as valid. + * + * Triggered on weather updates with previously handled or no + * location changes. + */ +static void +on_gweather_update (GWeatherInfo *info, + GcalWeatherService *self) +{ + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + g_return_if_fail (info == NULL || GWEATHER_IS_INFO (info)); + + update_weather (self, info, TRUE); +} + +/* on_duration_timer_timeout + * @self: A #GcalWeatherService. + * + * Handles scheduled weather report updates. + */ +static void +on_duration_timer_timeout (GcalTimer *timer, + GcalWeatherService *self) +{ + g_return_if_fail (timer != NULL); + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + + if (self->gweather_info != NULL) + gweather_info_update (self->gweather_info); +} + +/* on_midnight_timer_timeout + * @self: A #GcalWeatherService. + * + * Handles scheduled weather report updates. + */ +static void +on_midnight_timer_timeout (GcalTimer *timer, + GcalWeatherService *self) +{ + g_return_if_fail (timer != NULL); + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + + if (self->gweather_info != NULL) + gweather_info_update (self->gweather_info); + + if (gcal_timer_is_running (self->duration_timer)) + gcal_timer_reset (self->duration_timer); + + schedule_midnight (self); +} + + + +/* + * Intenral timer Helpers: + */ + +/* update_timeout_interval: + * @self: The #GcalWeatherService instance. + * + * Selects the right duration timer timeout based + * on locally-stored weather information. + */ +static void +update_timeout_interval (GcalWeatherService *self) +{ + guint interval; + + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + + if (has_valid_weather_infos (self)) + interval = self->check_interval_renew; + else + interval = self->check_interval_new; + + gcal_timer_set_default_duration (self->duration_timer, interval); +} + +/* schedule_midnight: + * @self: The #GcalWeatherService instance. + * + * Sets the midnight timer timeout to midnight. + * The timer needs to be reset when it + * emits. + */ +static void +schedule_midnight (GcalWeatherService *self) +{ + g_autoptr (GTimeZone) zone = NULL; + g_autoptr (GDateTime) now = NULL; + g_autoptr (GDateTime) tom = NULL; + g_autoptr (GDateTime) mid = NULL; + gint64 real_now; + gint64 real_mid; + + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + + zone = (self->time_zone == NULL) + ? g_time_zone_new_local () + : g_time_zone_ref (self->time_zone); + + now = g_date_time_new_now (zone); + tom = g_date_time_add_days (now, 1); + mid = g_date_time_new (zone, + g_date_time_get_year (tom), + g_date_time_get_month (tom), + g_date_time_get_day_of_month (tom), + 0, 0, 0); + + real_mid = g_date_time_to_unix (mid); + real_now = g_date_time_to_unix (now); + + gcal_timer_set_default_duration (self->midnight_timer, + real_mid - real_now); +} + +/* start_timer: + * @self: The #GcalWeatherService instance. + * + * Starts weather timer in case it makes sense. + */ +static void +start_timer (GcalWeatherService *self) +{ + GNetworkMonitor *monitor; /* unowned */ + + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + + monitor = g_network_monitor_get_default (); + if (g_network_monitor_get_network_available (monitor)) + { + update_timeout_interval (self); + gcal_timer_start (self->duration_timer); + + schedule_midnight (self); + gcal_timer_start (self->midnight_timer); + } +} + +/* stop_timer: + * @self: The #GcalWeatherService instance. + * + * Stops the timer. + */ +static void +stop_timer (GcalWeatherService *self) +{ + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + + gcal_timer_stop (self->duration_timer); + gcal_timer_stop (self->midnight_timer); +} + + +/* + * Internal location API: + */ + +/** + * update_location: + * @self: The #GcalWeatherService instance. + * @location: (nullable): The location we want weather information for. + * + * Registers the location to retrieve weather information from. + */ +static void +update_location (GcalWeatherService *self, + GWeatherLocation *location) +{ + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + + if (gcal_timer_is_running (self->duration_timer)) + stop_timer (self); + + if (self->gweather_info != NULL) + g_clear_object (&self->gweather_info); + + if (location == NULL) + { + g_debug ("Could not retrieve current location"); + update_weather (self, NULL, FALSE); + } + else + { + g_debug ("Got new weather service location: '%s'", + (location == NULL)? "" : gweather_location_get_name (location)); + + self->gweather_info = gweather_info_new (location, GWEATHER_FORECAST_ZONE | GWEATHER_FORECAST_LIST); + + /* NOTE: We do not get detailed infos for GWEATHER_PROVIDER_ALL. + * This combination works fine, though. We should open a bug / investigate + * what is going on. + */ + gweather_info_set_enabled_providers (self->gweather_info, GWEATHER_PROVIDER_METAR | GWEATHER_PROVIDER_OWM | GWEATHER_PROVIDER_YR_NO); + g_signal_connect (self->gweather_info, "updated", (GCallback) on_gweather_update, self); + + /* gweather_info_update might or might not trigger a + * GWeatherInfo::update() signal. Therefore, we have to + * remove weather information before querying new one. + * This might result in icon flickering on screen. + * We probably want to introduce a "unknown" or "loading" + * state in gweather-info to soften the effect. + */ + update_weather (self, NULL, FALSE); + gweather_info_update (self->gweather_info); + + start_timer (self); + } +} + +/** + * update_gclue_location: + * @self: The #GcalWeatherService instance. + * @location: (nullable): The location we want weather information for. + * + * Registers the location to retrieve weather information from. + */ +static void +update_gclue_location (GcalWeatherService *self, + GClueLocation *location) +{ + GWeatherLocation *wlocation = NULL; /* owned */ + + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + g_return_if_fail (location == NULL || GCLUE_IS_LOCATION (location)); + + if (location != NULL) + { + GWeatherLocation *wworld; /* unowned */ + gdouble latitude; + gdouble longitude; + + latitude = gclue_location_get_latitude (location); + longitude = gclue_location_get_longitude (location); + + /* nearest-city works more closely to gnome weather. */ + wworld = gweather_location_get_world (); + wlocation = gweather_location_find_nearest_city (wworld, latitude, longitude); + } + + + update_location (self, wlocation); + + if (wlocation != NULL) + gweather_location_unref (wlocation); +} + + + +/* + * Internal Weather API + */ + +#if PRINT_WEATHER_DATA +static gchar* +gwc2str (GWeatherInfo *gwi) +{ + g_autoptr (GDateTime) date = NULL; + g_autofree gchar *date_str = NULL; + glong update; + + gchar *icon_name; /* unowned */ + gdouble temp; + + if (!gweather_info_get_value_update (gwi, &update)) + return g_strdup (""); + + date = g_date_time_new_from_unix_local (update); + date_str = g_date_time_format (date, "%F %T"), + + get_gweather_temperature (gwi, &temp); + icon_name = gweather_info_get_symbolic_icon_name (gwi); + + return g_strdup_printf ("(%s: t:%f, w:%s)", + date_str, + temp, + icon_name); +} +#endif + +/* set_max_days: + * @self: The #GcalWeatherService instance. + * @days: Number of days. + * + * Setter for #GcalWeatherInfos:max-days. + */ +static void +set_max_days (GcalWeatherService *self, + guint days) +{ + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + g_return_if_fail (days >= 1); + + self->max_days = days; + + g_object_notify ((GObject*) self, "max-days"); +} + +/* set_valid_timespan: + * @self: A #GcalWeatherService instance. + * @timespan: Amount of seconds we consider weather information as valid. + */ +static void +set_valid_timespan (GcalWeatherService *self, + gint64 timespan) +{ + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + g_return_if_fail (timespan >= 0); + + self->valid_timespan = timespan; + + g_object_notify ((GObject*) self, "valid-timespan"); +} + +/* has_valid_weather_infos + * @self: A #GcalWeatherService instance. + * + * Checks whether weather information are available + * and up-to-date. + */ +static gboolean +has_valid_weather_infos (GcalWeatherService *self) +{ + gint64 now; + + g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), FALSE); + + if (self->gweather_info == NULL || self->weather_infos_upated < 0) + return FALSE; + + now = g_get_monotonic_time (); + return (now - self->weather_infos_upated) / 1000000 <= self->valid_timespan; +} + +/* update_weather: + * @self: A #GcalWeatherService instance. + * @info: (nullable): Newly received weather information or %NULL. + * @reuse_old_on_error: Whether to re-use old but not outdated weather + * information in case we could not fetch new data. + * + * Retrieves weather information for @location and triggers + * #GcalWeatherService::weather-changed. + */ +static void +update_weather (GcalWeatherService *self, + GWeatherInfo *info, + gboolean reuse_old_on_error) +{ + GSList *gwforecast = NULL; /* unowned */ + + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + g_return_if_fail (info == NULL || GWEATHER_IS_INFO (info)); + + + /* Compute a list of newly received weather infos. */ + if (info == NULL) + { + g_debug ("Could not retrieve valid weather"); + } + else if (gweather_info_is_valid (info)) + { + g_debug ("Received valid weather information"); + gwforecast = gweather_info_get_forecast_list (info); + } + else + { + g_autofree gchar* location_name = gweather_info_get_location_name (info); + g_debug ("Could not retrieve valid weather for location '%s'", location_name); + } + + if (gwforecast == NULL && self->weather_infos_upated >= 0) + { + if (!reuse_old_on_error || !has_valid_weather_infos (self)) + { + g_slist_free_full (self->weather_infos, g_object_unref); + self->weather_infos = NULL; + self->weather_infos_upated = -1; + + g_signal_emit (self, gcal_weather_service_signals[SIG_WEATHER_CHANGED], 0); + } + } + else if (gwforecast != NULL) + { + g_slist_free_full (self->weather_infos, g_object_unref); + self->weather_infos = preprocess_gweather_reports (self, gwforecast); + self->weather_infos_upated = g_get_monotonic_time (); + + g_signal_emit (self, gcal_weather_service_signals[SIG_WEATHER_CHANGED], 0); + } +} + + + +/* + * Internal weather update API and callbacks + */ + +/* set_check_interval_new: + * @self: The #GcalWeatherService instance. + * @days: Number of days. + * + * Setter for GcalWeatherInfos:check-interval-new. + */ +static void +set_check_interval_new (GcalWeatherService *self, + guint interval) +{ + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + g_return_if_fail (interval > 0); + + self->check_interval_new = interval; + update_timeout_interval (self); + + g_object_notify ((GObject*) self, "check-interval-new"); +} + +/* set_check_interval_renew: + * @self: The #GcalWeatherService instance. + * @days: Number of days. + * + * Setter for GcalWeatherInfos:check-interval-renew. + */ +static void +set_check_interval_renew (GcalWeatherService *self, + guint interval) +{ + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + g_return_if_fail (interval > 0); + + self->check_interval_renew = interval; + update_timeout_interval (self); + + g_object_notify ((GObject*) self, "check-interval-renew"); +} + +/* drop_suffix: + * @str: A icon name to normalize. + * + * Translates a given weather icon name to the + * one to display for folded weather reports. + * + * Returns: Number of initial characters that + * belong to the normalized name. + */ +static gssize +get_normalized_icon_name_len (const gchar *str) +{ + const gchar suffix1[] = "-symbolic"; + const gssize suffix1_len = G_N_ELEMENTS (suffix1) - 1; + + const gchar suffix2[] = "-night"; + const gssize suffix2_len = G_N_ELEMENTS (suffix2) - 1; + + gssize clean_len; + gssize str_len; + + g_return_val_if_fail (str != NULL, -1); + + str_len = strlen (str); + + clean_len = str_len - suffix1_len; + if (clean_len >= 0 && memcmp (suffix1, str + clean_len, suffix1_len) == 0) + str_len = clean_len; + + clean_len = str_len - suffix2_len; + if (clean_len >= 0 && memcmp (suffix2, str + clean_len, suffix2_len) == 0) + str_len = clean_len; + + return str_len; +} /* get_icon_name_sortkey: * @@ -611,41 +1208,6 @@ get_icon_name_sortkey (const gchar *icon_name, return -1; } - - -/************** - * < private > - **************/ - -#if PRINT_WEATHER_DATA -static gchar* -gwc2str (GWeatherInfo *gwi) -{ - g_autoptr (GDateTime) date = NULL; - g_autofree gchar *date_str = NULL; - glong update; - - gchar *icon_name; /* unowned */ - gdouble temp; - - if (!gweather_info_get_value_update (gwi, &update)) - return g_strdup (""); - - date = g_date_time_new_from_unix_local (update); - date_str = g_date_time_format (date, "%F %T"), - - get_gweather_temperature (gwi, &temp); - icon_name = gweather_info_get_symbolic_icon_name (gwi); - - return g_strdup_printf ("(%s: t:%f, w:%s)", - date_str, - temp, - icon_name); -} -#endif - - - /* get_time_day_start: * @self: The #GcalWeatherService instance. * @date: (out) (not nullable): A #GDate that should be set to today. @@ -692,8 +1254,6 @@ get_time_day_start (GcalWeatherService *self, return TRUE; } - - /* get_gweather_temperature: * @gwi: #GWeatherInfo to extract temperatures from. * @temp: (out): extracted temperature or %NAN. @@ -734,8 +1294,6 @@ get_gweather_temperature (GWeatherInfo *gwi, } } - - /* compute_weather_info_data: * @samples: List of received #GWeatherInfos. * @icon_name: (out): (transfer full): weather icon name or %NULL. @@ -821,8 +1379,6 @@ compute_weather_info_data (GSList *samples, } } - - /* preprocess_gweather_reports: * @self: The #GcalWeatherService instance. * @samples: Received list of #GWeatherInfos @@ -951,596 +1507,6 @@ preprocess_gweather_reports (GcalWeatherService *self, } - -/** - * gcal_weather_service_update_location: - * @self: The #GcalWeatherService instance. - * @location: (nullable): The location we want weather information for. - * - * Registers the location to retrieve weather information from. - */ -static void -gcal_weather_service_update_location (GcalWeatherService *self, - GWeatherLocation *location) -{ - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - - if (gcal_timer_is_running (self->duration_timer)) - stop_timer (self); - - if (self->gweather_info != NULL) - g_clear_object (&self->gweather_info); - - if (location == NULL) - { - g_debug ("Could not retrieve current location"); - gcal_weather_service_update_weather (self, NULL, FALSE); - } - else - { - g_debug ("Got new weather service location: '%s'", - (location == NULL)? "" : gweather_location_get_name (location)); - - self->gweather_info = gweather_info_new (location, GWEATHER_FORECAST_ZONE | GWEATHER_FORECAST_LIST); - - /* NOTE: We do not get detailed infos for GWEATHER_PROVIDER_ALL. - * This combination works fine, though. We should open a bug / investigate - * what is going on. - */ - gweather_info_set_enabled_providers (self->gweather_info, GWEATHER_PROVIDER_METAR | GWEATHER_PROVIDER_OWM | GWEATHER_PROVIDER_YR_NO); - g_signal_connect (self->gweather_info, "updated", (GCallback) on_gweather_update, self); - - /* gweather_info_update might or might not trigger a - * GWeatherInfo::update() signal. Therefore, we have to - * remove weather information before querying new one. - * This might result in icon flickering on screen. - * We probably want to introduce a "unknown" or "loading" - * state in gweather-info to soften the effect. - */ - gcal_weather_service_update_weather (self, NULL, FALSE); - gweather_info_update (self->gweather_info); - - start_timer (self); - } -} - - - -/** - * gcal_weather_service_update_gclue_location: - * @self: The #GcalWeatherService instance. - * @location: (nullable): The location we want weather information for. - * - * Registers the location to retrieve weather information from. - */ -static void -gcal_weather_service_update_gclue_location (GcalWeatherService *self, - GClueLocation *location) -{ - GWeatherLocation *wlocation = NULL; /* owned */ - - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - g_return_if_fail (location == NULL || GCLUE_IS_LOCATION (location)); - - if (location != NULL) - { - GWeatherLocation *wworld; /* unowned */ - gdouble latitude; - gdouble longitude; - - latitude = gclue_location_get_latitude (location); - longitude = gclue_location_get_longitude (location); - - /* nearest-city works more closely to gnome weather. */ - wworld = gweather_location_get_world (); - wlocation = gweather_location_find_nearest_city (wworld, latitude, longitude); - } - - - gcal_weather_service_update_location (self, wlocation); - - if (wlocation != NULL) - gweather_location_unref (wlocation); -} - - - -/* on_gclue_simple_creation: - * @source: - * @result: Result of gclue_simple_new(). - * @self: (transfer full): A GcalWeatherService reference. - * - * Callback used in gcal_weather_service_run(). - */ -static void -on_gclue_simple_creation (GClueSimple *_source, - GAsyncResult *result, - GcalWeatherService *self) -{ - GClueSimple *location_service; /* owned */ - GClueLocation *location; /* unowned */ - GClueClient *client; /* unowned */ - g_autoptr (GError) error = NULL; - - g_return_if_fail (G_IS_ASYNC_RESULT (result)); - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - - /* make sure we do not touch self->location_service - * if the current operation was cancelled. - */ - location_service = gclue_simple_new_finish (result, &error); - if (error != NULL) - { - g_assert (location_service == NULL); - - if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_CANCELLED) - /* Cancelled during creation. Silently fail. */; - else - g_warning ("Could not create GCLueSimple: %s", error->message); - - g_object_unref (self); - return; - } - - g_assert (self->location_service == NULL); - g_assert (location_service != NULL); - - self->location_service = g_steal_pointer (&location_service); - - location = gclue_simple_get_location (self->location_service); - client = gclue_simple_get_client (self->location_service); - - if (location != NULL) - { - gcal_weather_service_update_gclue_location (self, location); - - g_signal_connect_object (location, - "notify::location", - G_CALLBACK (on_gclue_location_changed), - self, - 0); - } - - g_signal_connect_object (client, - "notify::active", - G_CALLBACK (on_gclue_client_activity_changed), - self, - 0); - - g_object_unref (self); -} - - -/* on_gclue_location_changed: - * @location: #GClueLocation owned by @self - * @self: The #GcalWeatherService - * - * Handles location changes. - */ -static void -on_gclue_location_changed (GClueLocation *location, - GcalWeatherService *self) -{ - g_return_if_fail (GCLUE_IS_LOCATION (location)); - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - - gcal_weather_service_update_gclue_location (self, location); -} - - - -/* on_gclue_client_activity_changed: - * @client: The #GClueclient ownd by @self - * @self: The #GcalWeatherService - * - * Handles location client activity changes. - */ -static void -on_gclue_client_activity_changed (GClueClient *client, - GcalWeatherService *self) -{ - g_return_if_fail (GCLUE_IS_CLIENT (client)); - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - - /* Notify listeners about unknown locations: */ - gcal_weather_service_update_location (self, NULL); -} - - - -/* on_gclue_client_stop: - * @source_object: A #GClueClient. - * @res: Result of gclue_client_call_stop(). - * @simple: (transfer full): A #GClueSimple. - * - * Helper-callback used in gcal_weather_service_stop(). - */ -static void -on_gclue_client_stop (GClueClient *client, - GAsyncResult *res, - GClueSimple *simple) -{ - g_autoptr(GError) error = NULL; /* owned */ - gboolean stopped; - - g_return_if_fail (GCLUE_IS_CLIENT (client)); - g_return_if_fail (G_IS_ASYNC_RESULT (res)); - g_return_if_fail (GCLUE_IS_SIMPLE (simple)); - - stopped = gclue_client_call_stop_finish (client, - res, - &error); - if (error != NULL) - g_warning ("Could not stop location service: %s", error->message); - else if (!stopped) - g_warning ("Could not stop location service"); - - g_object_unref (simple); -} - - - -/* gcal_weather_service_set_max_days: - * @self: The #GcalWeatherService instance. - * @days: Number of days. - * - * Setter for #GcalWeatherInfos:max-days. - */ -static void -gcal_weather_service_set_max_days (GcalWeatherService *self, - guint days) -{ - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - g_return_if_fail (days >= 1); - - self->max_days = days; - - g_object_notify ((GObject*) self, "max-days"); -} - - - -/* gcal_weather_service_set_valid_timespan: - * @self: A #GcalWeatherService instance. - * @timespan: Amount of seconds we consider weather information as valid. - */ -static void -gcal_weather_service_set_valid_timespan (GcalWeatherService *self, - gint64 timespan) -{ - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - g_return_if_fail (timespan >= 0); - - self->valid_timespan = timespan; - - g_object_notify ((GObject*) self, "valid-timespan"); -} - - - -/* has_valid_weather_infos - * @self: A #GcalWeatherService instance. - * - * Checks whether weather information are available - * and up-to-date. - */ -static gboolean -has_valid_weather_infos (GcalWeatherService *self) -{ - gint64 now; - - g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), FALSE); - - if (self->gweather_info == NULL || self->weather_infos_upated < 0) - return FALSE; - - now = g_get_monotonic_time (); - return (now - self->weather_infos_upated) / 1000000 <= self->valid_timespan; -} - - - -/* gcal_weather_service_update_weather: - * @self: A #GcalWeatherService instance. - * @info: (nullable): Newly received weather information or %NULL. - * @reuse_old_on_error: Whether to re-use old but not outdated weather - * information in case we could not fetch new data. - * - * Retrieves weather information for @location and triggers - * #GcalWeatherService::weather-changed. - */ -static void -gcal_weather_service_update_weather (GcalWeatherService *self, - GWeatherInfo *info, - gboolean reuse_old_on_error) -{ - GSList *gwforecast = NULL; /* unowned */ - - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - g_return_if_fail (info == NULL || GWEATHER_IS_INFO (info)); - - - /* Compute a list of newly received weather infos. */ - if (info == NULL) - { - g_debug ("Could not retrieve valid weather"); - } - else if (gweather_info_is_valid (info)) - { - g_debug ("Received valid weather information"); - gwforecast = gweather_info_get_forecast_list (info); - } - else - { - g_autofree gchar* location_name = gweather_info_get_location_name (info); - g_debug ("Could not retrieve valid weather for location '%s'", location_name); - } - - if (gwforecast == NULL && self->weather_infos_upated >= 0) - { - if (!reuse_old_on_error || !has_valid_weather_infos (self)) - { - g_slist_free_full (self->weather_infos, g_object_unref); - self->weather_infos = NULL; - self->weather_infos_upated = -1; - - g_signal_emit (self, gcal_weather_service_signals[SIG_WEATHER_CHANGED], 0); - } - } - else if (gwforecast != NULL) - { - g_slist_free_full (self->weather_infos, g_object_unref); - self->weather_infos = preprocess_gweather_reports (self, gwforecast); - self->weather_infos_upated = g_get_monotonic_time (); - - g_signal_emit (self, gcal_weather_service_signals[SIG_WEATHER_CHANGED], 0); - } -} - - - -/* on_gweather_update: - * @self: A #GcalWeatherService instance. - * @timespan: Amount of seconds we consider weather information as valid. - * - * Triggered on weather updates with previously handled or no - * location changes. - */ -static void -on_gweather_update (GWeatherInfo *info, - GcalWeatherService *self) -{ - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - g_return_if_fail (info == NULL || GWEATHER_IS_INFO (info)); - - gcal_weather_service_update_weather (self, info, TRUE); -} - - - -/* update_timeout_interval: - * @self: The #GcalWeatherService instance. - * - * Selects the right duration timer timeout based - * on locally-stored weather information. - */ -static void -update_timeout_interval (GcalWeatherService *self) -{ - guint interval; - - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - - if (has_valid_weather_infos (self)) - interval = self->check_interval_renew; - else - interval = self->check_interval_new; - - gcal_timer_set_default_duration (self->duration_timer, interval); -} - - - -/* schedule_midnight: - * @self: The #GcalWeatherService instance. - * - * Sets the midnight timer timeout to midnight. - * The timer needs to be reset when it - * emits. - */ -static void -schedule_midnight (GcalWeatherService *self) -{ - g_autoptr (GTimeZone) zone = NULL; - g_autoptr (GDateTime) now = NULL; - g_autoptr (GDateTime) tom = NULL; - g_autoptr (GDateTime) mid = NULL; - gint64 real_now; - gint64 real_mid; - - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - - zone = (self->time_zone == NULL) - ? g_time_zone_new_local () - : g_time_zone_ref (self->time_zone); - - now = g_date_time_new_now (zone); - tom = g_date_time_add_days (now, 1); - mid = g_date_time_new (zone, - g_date_time_get_year (tom), - g_date_time_get_month (tom), - g_date_time_get_day_of_month (tom), - 0, 0, 0); - - real_mid = g_date_time_to_unix (mid); - real_now = g_date_time_to_unix (now); - - gcal_timer_set_default_duration (self->midnight_timer, - real_mid - real_now); -} - - - -/* start_timer: - * @self: The #GcalWeatherService instance. - * - * Starts weather timer in case it makes sense. - */ -static void -start_timer (GcalWeatherService *self) -{ - GNetworkMonitor *monitor; /* unowned */ - - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - - monitor = g_network_monitor_get_default (); - if (g_network_monitor_get_network_available (monitor)) - { - update_timeout_interval (self); - gcal_timer_start (self->duration_timer); - - schedule_midnight (self); - gcal_timer_start (self->midnight_timer); - } -} - - - -/* stop_timer: - * @self: The #GcalWeatherService instance. - * - * Stops the timer. - */ -static void -stop_timer (GcalWeatherService *self) -{ - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - - gcal_timer_stop (self->duration_timer); - gcal_timer_stop (self->midnight_timer); -} - - - -/* on_network_change: - * @monitor: The emitting #GNetworkMonitor - * @available: The current value of “network-available” - * @self: The #GcalWeatherService instance. - * - * Starts and stops timer based on monitored network - * changes. - */ -static void -on_network_change (GNetworkMonitor *monitor, - gboolean available, - GcalWeatherService *self) -{ - gboolean is_running; - - g_return_if_fail (G_IS_NETWORK_MONITOR (monitor)); - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - - g_debug ("network changed, available = %d", available); - - is_running = gcal_timer_is_running (self->duration_timer); - if (available && !is_running) - { - if (self->gweather_info != NULL) - gweather_info_update (self->gweather_info); - - start_timer (self); - } - else if (!available && is_running) - { - stop_timer (self); - } -} - - - -/* gcal_weather_service_set_check_interval_new: - * @self: The #GcalWeatherService instance. - * @days: Number of days. - * - * Setter for GcalWeatherInfos:check-interval-new. - */ -static void -gcal_weather_service_set_check_interval_new (GcalWeatherService *self, - guint interval) -{ - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - g_return_if_fail (interval > 0); - - self->check_interval_new = interval; - update_timeout_interval (self); - - g_object_notify ((GObject*) self, "check-interval-new"); -} - - - -/* gcal_weather_service_set_check_interval_renew: - * @self: The #GcalWeatherService instance. - * @days: Number of days. - * - * Setter for GcalWeatherInfos:check-interval-renew. - */ -static void -gcal_weather_service_set_check_interval_renew (GcalWeatherService *self, - guint interval) -{ - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - g_return_if_fail (interval > 0); - - self->check_interval_renew = interval; - update_timeout_interval (self); - - g_object_notify ((GObject*) self, "check-interval-renew"); -} - - - -/* on_duration_timer_timeout - * @self: A #GcalWeatherService. - * - * Handles scheduled weather report updates. - */ -static void -on_duration_timer_timeout (GcalTimer *timer, - GcalWeatherService *self) -{ - g_return_if_fail (timer != NULL); - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - - if (self->gweather_info != NULL) - gweather_info_update (self->gweather_info); -} - - - -/* on_midnight_timer_timeout - * @self: A #GcalWeatherService. - * - * Handles scheduled weather report updates. - */ -static void -on_midnight_timer_timeout (GcalTimer *timer, - GcalWeatherService *self) -{ - g_return_if_fail (timer != NULL); - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - - if (self->gweather_info != NULL) - gweather_info_update (self->gweather_info); - - if (gcal_timer_is_running (self->duration_timer)) - gcal_timer_reset (self->duration_timer); - - schedule_midnight (self); -} - - - /************* * < public > *************/ @@ -1572,7 +1538,160 @@ gcal_weather_service_new (GTimeZone *time_zone, NULL); } +/** + * gcal_weather_service_get_time_zone: + * @self: The #GcalWeatherService instance. + * + * Getter for #GcalWeatherService:time-zone. + */ +GTimeZone* +gcal_weather_service_get_time_zone (GcalWeatherService *self) +{ + g_return_val_if_fail (self != NULL, NULL); + return self->time_zone; +} +/** + * gcal_weather_service_set_time_zone: + * @self: The #GcalWeatherService instance. + * @days: Number of days. + * + * Setter for #GcalWeatherInfos:time-zone. + */ +void +gcal_weather_service_set_time_zone (GcalWeatherService *self, + GTimeZone *value) +{ + g_return_if_fail (self != NULL); + + if (self->time_zone != value) + { + if (self->time_zone != NULL) + { + g_time_zone_unref (self->time_zone); + self->time_zone = NULL; + } + + if (value != NULL) + self->time_zone = g_time_zone_ref (value); + + /* make sure we provide correct weather infos */ + gweather_info_update (self->gweather_info); + + /* make sure midnight is timed correctly: */ + schedule_midnight (self); + + g_object_notify ((GObject*) self, "time-zone"); + } +} + +/** + * gcal_weather_service_get_max_days: + * @self: The #GcalWeatherService instance. + * + * Getter for #GcalWeatherService:max-days. + */ +guint +gcal_weather_service_get_max_days (GcalWeatherService *self) +{ + g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), 0); + + return self->max_days; +} + +/** + * gcal_weather_service_get_valid_timespan: + * @self: The #GcalWeatherService instance. + * + * Getter for #GcalWeatherService:valid-interval. + */ +gint64 +gcal_weather_service_get_valid_timespan (GcalWeatherService *self) +{ + g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), 0); + return self->valid_timespan; +} + +/** + * gcal_weather_service_get_check_interval_new: + * @self: The #GcalWeatherService instance. + * + * Getter for #GcalWeatherService:check-interval-new. + */ +guint +gcal_weather_service_get_check_interval_new (GcalWeatherService *self) +{ + g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), 0); + + return self->check_interval_new; +} + +/** + * gcal_weather_service_get_check_interval_renew: + * @self: The #GcalWeatherService instance. + * + * Getter for #GcalWeatherService:check-interval-renew. + */ +guint +gcal_weather_service_get_check_interval_renew (GcalWeatherService *self) +{ + g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), 0); + + return self->check_interval_renew; +} + +/** + * gcal_weather_service_get_weather_infos: + * @self: The #GcalWeatherService instance. + * + * Returns: (transfer none): list of known weather reports. + */ +GSList* +gcal_weather_service_get_weather_infos (GcalWeatherService *self) +{ + g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), NULL); + + return self->weather_infos; +} + +/** + * gcal_weather_service_get_attribution: + * @self: The #GcalWeatherService instance. + * + * Returns weather service attribution. + * + * Returns: (nullable) (transfer none): Text to display. + */ +const gchar* +gcal_weather_service_get_attribution (GcalWeatherService *self) +{ + g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), NULL); + + if (self->gweather_info != NULL) + return gweather_info_get_attribution (self->gweather_info); + + return NULL; +} + +/** + * gcal_weather_service_update: + * @self: The #GcalWeatherService instance. + * + * Tries to update weather reports. + */ +void +gcal_weather_service_update (GcalWeatherService *self) +{ + g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); + + if (self->gweather_info != NULL) + { + gweather_info_update (self->gweather_info); + update_timeout_interval (self); + if (gcal_timer_is_running (self->duration_timer)) + gcal_timer_reset (self->duration_timer); + } +} /** * gcal_weather_service_run: @@ -1613,12 +1732,10 @@ gcal_weather_service_run (GcalWeatherService *self, self->weather_service_running = TRUE; /*_update_location starts timer if necessary */ - gcal_weather_service_update_location (self, location); + update_location (self, location); } } - - /** * gcal_weather_service_stop: * @self: The #GcalWeatherService instance. @@ -1640,7 +1757,7 @@ gcal_weather_service_stop (GcalWeatherService *self) self->weather_service_running = FALSE; /* Notify all listeners about unknown location: */ - gcal_weather_service_update_location (self, NULL); + update_location (self, NULL); if (self->location_service == NULL) { @@ -1659,177 +1776,3 @@ gcal_weather_service_stop (GcalWeatherService *self) g_steal_pointer (&self->location_service)); } } - - - -/** - * gcal_weather_service_get_max_days: - * @self: The #GcalWeatherService instance. - * - * Getter for #GcalWeatherService:max-days. - */ -guint -gcal_weather_service_get_max_days (GcalWeatherService *self) -{ - g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), 0); - - return self->max_days; -} - - - -/** - * gcal_weather_service_get_valid_timespan: - * @self: The #GcalWeatherService instance. - * - * Getter for #GcalWeatherService:valid-interval. - */ -gint64 -gcal_weather_service_get_valid_timespan (GcalWeatherService *self) -{ - g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), 0); - return self->valid_timespan; -} - - - -/** - * gcal_weather_service_get_time_zone: - * @self: The #GcalWeatherService instance. - * - * Getter for #GcalWeatherService:time-zone. - */ -GTimeZone* -gcal_weather_service_get_time_zone (GcalWeatherService *self) -{ - g_return_val_if_fail (self != NULL, NULL); - return self->time_zone; -} - - - -/** - * gcal_weather_service_set_time_zone: - * @self: The #GcalWeatherService instance. - * @days: Number of days. - * - * Setter for #GcalWeatherInfos:time-zone. - */ -void -gcal_weather_service_set_time_zone (GcalWeatherService *self, - GTimeZone *value) -{ - g_return_if_fail (self != NULL); - - if (self->time_zone != value) - { - if (self->time_zone != NULL) - { - g_time_zone_unref (self->time_zone); - self->time_zone = NULL; - } - - if (value != NULL) - self->time_zone = g_time_zone_ref (value); - - /* make sure we provide correct weather infos */ - gweather_info_update (self->gweather_info); - - /* make sure midnight is timed correctly: */ - schedule_midnight (self); - - g_object_notify ((GObject*) self, "time-zone"); - } -} - - - - -/** - * gcal_weather_service_get_check_interval_new: - * @self: The #GcalWeatherService instance. - * - * Getter for #GcalWeatherService:check-interval-new. - */ -guint -gcal_weather_service_get_check_interval_new (GcalWeatherService *self) -{ - g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), 0); - - return self->check_interval_new; -} - - - -/** - * gcal_weather_service_get_check_interval_renew: - * @self: The #GcalWeatherService instance. - * - * Getter for #GcalWeatherService:check-interval-renew. - */ -guint -gcal_weather_service_get_check_interval_renew (GcalWeatherService *self) -{ - g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), 0); - - return self->check_interval_renew; -} - - - -/** - * gcal_weather_service_get_weather_infos: - * @self: The #GcalWeatherService instance. - * - * Returns: (transfer none): list of known weather reports. - */ -GSList* -gcal_weather_service_get_weather_infos (GcalWeatherService *self) -{ - g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), NULL); - - return self->weather_infos; -} - - - -/** - * gcal_weather_service_get_attribution: - * @self: The #GcalWeatherService instance. - * - * Returns weather service attribution. - * - * Returns: (nullable) (transfer none): Text to display. - */ -const gchar* -gcal_weather_service_get_attribution (GcalWeatherService *self) -{ - g_return_val_if_fail (GCAL_IS_WEATHER_SERVICE (self), NULL); - - if (self->gweather_info != NULL) - return gweather_info_get_attribution (self->gweather_info); - - return NULL; -} - - - -/** - * gcal_weather_service_update: - * @self: The #GcalWeatherService instance. - * - * Tries to update weather reports. - */ -void -gcal_weather_service_update (GcalWeatherService *self) -{ - g_return_if_fail (GCAL_IS_WEATHER_SERVICE (self)); - - if (self->gweather_info != NULL) - { - gweather_info_update (self->gweather_info); - update_timeout_interval (self); - if (gcal_timer_is_running (self->duration_timer)) - gcal_timer_reset (self->duration_timer); - } -} diff --git a/src/gcal-weather-service.h b/src/gcal-weather-service.h index b9093d08..52f78d40 100644 --- a/src/gcal-weather-service.h +++ b/src/gcal-weather-service.h @@ -37,37 +37,35 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (GcalWeatherService, gcal_weather_service, GCAL, WEATHER_SERVICE, GObject) -GcalWeatherService* gcal_weather_service_new (GTimeZone *time_zone, - guint max_days, - guint check_interval_new, - guint check_interval_renew, - gint64 valid_timespan); +GcalWeatherService* gcal_weather_service_new (GTimeZone *time_zone, + guint max_days, + guint check_interval_new, + guint check_interval_renew, + gint64 valid_timespan); -GTimeZone* gcal_weather_service_get_time_zone (GcalWeatherService *self); +GTimeZone* gcal_weather_service_get_time_zone (GcalWeatherService *self); -void gcal_weather_service_set_time_zone (GcalWeatherService *self, - GTimeZone *value); +void gcal_weather_service_set_time_zone (GcalWeatherService *self, + GTimeZone *value); -void gcal_weather_service_run (GcalWeatherService *self, - GWeatherLocation *location); +guint gcal_weather_service_get_max_days (GcalWeatherService *self); -void gcal_weather_service_stop (GcalWeatherService *self); +gint64 gcal_weather_service_get_valid_timespan (GcalWeatherService *self); -guint gcal_weather_service_get_max_days (GcalWeatherService *self); +guint gcal_weather_service_get_check_interval_new (GcalWeatherService *self); -gint64 gcal_weather_service_get_valid_timespan (GcalWeatherService *self); +guint gcal_weather_service_get_check_interval_renew (GcalWeatherService *self); -guint gcal_weather_service_get_check_interval_new - (GcalWeatherService *self); +GSList* gcal_weather_service_get_weather_infos (GcalWeatherService *self); -guint gcal_weather_service_get_check_interval_renew - (GcalWeatherService *self); +const gchar* gcal_weather_service_get_attribution (GcalWeatherService *self); -GSList* gcal_weather_service_get_weather_infos (GcalWeatherService *self); +void gcal_weather_service_update (GcalWeatherService *self); -const gchar* gcal_weather_service_get_attribution (GcalWeatherService *self); +void gcal_weather_service_run (GcalWeatherService *self, + GWeatherLocation *location); -void gcal_weather_service_update (GcalWeatherService *self); +void gcal_weather_service_stop (GcalWeatherService *self); G_END_DECLS diff --git a/src/gcal-window.c b/src/gcal-window.c index c6c09756..5fb6e9ad 100644 --- a/src/gcal-window.c +++ b/src/gcal-window.c @@ -84,16 +84,16 @@ typedef struct { - gint x; - gint y; - GDateTime *start_date; - GDateTime *end_date; + gint x; + gint y; + GDateTime *start_date; + GDateTime *end_date; } NewEventData; typedef struct { - GcalWindow *window; - gchar *uuid; + GcalWindow *window; + gchar *uuid; } OpenEditDialogData; /* WeatherSigs: @@ -107,8 +107,8 @@ typedef struct */ typedef struct { - GObject *obj; /* unowned */ - gulong id; + GObject *obj; /* unowned */ + gulong id; } WeatherSigs; struct _GcalWindow @@ -116,86 +116,86 @@ struct _GcalWindow GtkApplicationWindow parent; /* timeout ids */ - guint notification_timeout; + guint notification_timeout; /* upper level widgets */ - GtkWidget *main_box; + GtkWidget *main_box; - GtkWidget *header_bar; - GtkWidget *search_bar; - GtkWidget *views_overlay; - GtkWidget *views_stack; - GtkWidget *week_view; - GtkWidget *month_view; - GtkWidget *year_view; - GtkWidget *notification; - GtkWidget *notification_label; - GtkWidget *notification_action_button; - GtkWidget *notification_close_button; + GtkWidget *header_bar; + GtkWidget *search_bar; + GtkWidget *views_overlay; + GtkWidget *views_stack; + GtkWidget *week_view; + GtkWidget *month_view; + GtkWidget *year_view; + GtkWidget *notification; + GtkWidget *notification_label; + GtkWidget *notification_action_button; + GtkWidget *notification_close_button; /* header_bar widets */ - GtkWidget *menu_button; - GtkWidget *search_button; - GtkWidget *calendars_button; - GtkWidget *search_entry; - GtkWidget *back_button; - GtkWidget *today_button; - GtkWidget *forward_button; - GtkWidget *views_switcher; + GtkWidget *menu_button; + GtkWidget *search_button; + GtkWidget *calendars_button; + GtkWidget *search_entry; + GtkWidget *back_button; + GtkWidget *today_button; + GtkWidget *forward_button; + GtkWidget *views_switcher; /* new event popover widgets */ - GtkWidget *quick_add_popover; + GtkWidget *quick_add_popover; - GtkWidget *search_view; + GtkWidget *search_view; /* day, week, month, year, list */ - GtkWidget *views [6]; - GtkWidget *edit_dialog; + GtkWidget *views [6]; + GtkWidget *edit_dialog; - GcalManager *manager; - GcalWindowViewType active_view; - icaltimetype *active_date; + GcalManager *manager; + GcalWindowViewType active_view; + icaltimetype *active_date; - gboolean rtl; + gboolean rtl; /* states */ - gboolean new_event_mode; - gboolean search_mode; + gboolean new_event_mode; + gboolean search_mode; - NewEventData *event_creation_data; + NewEventData *event_creation_data; - GcalEvent *event_to_delete; - GcalRecurrenceModType event_to_delete_mod; + GcalEvent *event_to_delete; + GcalRecurrenceModType event_to_delete_mod; /* calendar management */ - GtkWidget *calendar_popover; - GtkWidget *calendar_listbox; - GtkWidget *source_dialog; + GtkWidget *calendar_popover; + GtkWidget *calendar_listbox; + GtkWidget *source_dialog; - gint refresh_timeout; - gint refresh_timeout_id; - gint open_edit_dialog_timeout_id; + gint refresh_timeout; + gint refresh_timeout_id; + gint open_edit_dialog_timeout_id; /* weather management */ - GcalWeatherService *weather_service; /* owned */ - GtkSwitch *weather; /* unowned */ - GtkSwitch *auto_location; /* unowned */ - GtkBox *auto_location_box; /* unowned */ + GcalWeatherService *weather_service; /* owned */ + GtkSwitch *weather; /* unowned */ + GtkSwitch *auto_location; /* unowned */ + GtkBox *auto_location_box; /* unowned */ GWeatherLocationEntry *location_entry; /* unowned */ - WeatherSigs weather_cb_ids[5]; + WeatherSigs weather_cb_ids[5]; /* temp to keep event_creation */ - gboolean open_edit_dialog; + gboolean open_edit_dialog; /* handler for the searh_view */ - gint click_outside_handler_id; + gint click_outside_handler_id; /* Window states */ - gint width; - gint height; - gint pos_x; - gint pos_y; - gboolean is_maximized; + gint width; + gint height; + gint pos_x; + gint pos_y; + gboolean is_maximized; }; enum @@ -218,60 +218,60 @@ enum } -static void on_show_calendars_action_activated (GSimpleAction *action, - GVariant *param, - gpointer user_data); +static void on_show_calendars_action_activated (GSimpleAction *action, + GVariant *param, + gpointer user_data); -static void on_view_action_activated (GSimpleAction *action, - GVariant *param, - gpointer user_data); +static void on_view_action_activated (GSimpleAction *action, + GVariant *param, + gpointer user_data); -static void on_toggle_search_bar_activated (GSimpleAction *action, - GVariant *param, - gpointer user_data); +static void on_menu_button_clicked (GtkMenuButton *menu, + GtkStack *stack); -static void on_menu_button_clicked (GtkMenuButton *menu, - GtkStack *stack); +static void on_toggle_search_bar_activated (GSimpleAction *action, + GVariant *param, + gpointer user_data); -static void on_view_menu_open_sub (GtkModelButton *button, - GtkStack *stack); +static void on_view_menu_open_sub (GtkModelButton *button, + GtkStack *stack); -static void on_view_menu_open_parent (GtkModelButton *button, - GtkStack *stack); +static void on_view_menu_open_parent (GtkModelButton *button, + GtkStack *stack); -static void on_weather_location_searchbox_change (GWeatherLocationEntry *entry, - GcalWindow *self); +static void on_weather_location_searchbox_change (GWeatherLocationEntry *entry, + GcalWindow *self); -static void on_show_weather_change (GtkSwitch *wswitch, - GParamSpec *pspec, - GcalWindow *self); +static void on_show_weather_change (GtkSwitch *wswitch, + GParamSpec *pspec, + GcalWindow *self); -static void on_auto_location_change (GtkSwitch *lswitch, - GParamSpec *pspec, - GcalWindow *self); +static void on_auto_location_change (GtkSwitch *lswitch, + GParamSpec *pspec, + GcalWindow *self); -static gboolean on_weather_location_searchbox_match_selected - (GtkEntryCompletion *sender, - GtkTreeModel *model, - GtkTreeIter *iter, - GcalWindow *self); +static gboolean on_weather_location_searchbox_match_selected (GtkEntryCompletion *sender, + GtkTreeModel *model, + GtkTreeIter *iter, + GcalWindow *self); -static void set_model_button_animation (GtkBuilder *builder, - GtkStack *stack, - const char *id, - gboolean go_back); -static void update_menu_weather_sensitivity (GcalWindow *self); +static void set_model_button_animation (GtkBuilder *builder, + GtkStack *stack, + const char *id, + gboolean go_back); + +static void update_menu_weather_sensitivity (GcalWindow *self); -static void close_menu (GcalWindow *self); +static void close_menu (GcalWindow *self); -static void safe_weather_settings (GcalWindow *self); +static void safe_weather_settings (GcalWindow *self); -static void load_weather_settings (GcalWindow *self); +static void load_weather_settings (GcalWindow *self); -static void manage_weather_service (GcalWindow *self); +static void manage_weather_service (GcalWindow *self); -static GWeatherLocation* get_checked_fixed_location (GcalWindow *self); +static GWeatherLocation* get_checked_fixed_location (GcalWindow *self); G_DEFINE_TYPE (GcalWindow, gcal_window, GTK_TYPE_APPLICATION_WINDOW) diff --git a/src/views/gcal-week-header.c b/src/views/gcal-week-header.c index 8d48c234..8e9fc600 100644 --- a/src/views/gcal-week-header.c +++ b/src/views/gcal-week-header.c @@ -48,57 +48,57 @@ */ typedef struct { - GcalWeatherInfo *winfo; /* owned */ - GdkPixbuf *icon_buf; /* owned */ + GcalWeatherInfo *winfo; /* owned */ + GdkPixbuf *icon_buf; /* owned */ } WeatherInfoDay; struct _GcalWeekHeader { - GtkGrid parent; + GtkGrid parent; - GtkWidget *grid; - GtkWidget *month_label; - GtkWidget *week_label; - GtkWidget *year_label; - GtkWidget *scrolledwindow; - GtkWidget *expand_button; - GtkWidget *expand_button_box; - GtkWidget *expand_button_image; - GtkWidget *header_labels_box; + GtkWidget *grid; + GtkWidget *month_label; + GtkWidget *week_label; + GtkWidget *year_label; + GtkWidget *scrolledwindow; + GtkWidget *expand_button; + GtkWidget *expand_button_box; + GtkWidget *expand_button_image; + GtkWidget *header_labels_box; - GcalManager *manager; + GcalManager *manager; /* * Stores the events as they come from the week-view * The list will later be iterated after the active date is changed * and the events will be placed */ - GList *events[7]; - GtkWidget *overflow_label[7]; + GList *events[7]; + GtkWidget *overflow_label[7]; - gint first_weekday; + gint first_weekday; /* * Used for checking if the header is in collapsed state or expand state * false is collapse state true is expand state */ - gboolean expanded; + gboolean expanded; - gboolean use_24h_format; + gboolean use_24h_format; - icaltimetype *active_date; + icaltimetype *active_date; - gint selection_start; - gint selection_end; - gint dnd_cell; + gint selection_start; + gint selection_end; + gint dnd_cell; GcalWeatherService *weather_service; /* unowned, nullable */ /* Array of nullable weather infos for each day, starting with Sunday. */ WeatherInfoDay weather_infos[7]; - GtkSizeGroup *sizegroup; + GtkSizeGroup *sizegroup; }; typedef enum diff --git a/src/views/gcal-week-view.c b/src/views/gcal-week-view.c index 7290b957..bc1122fe 100644 --- a/src/views/gcal-week-view.c +++ b/src/views/gcal-week-view.c @@ -43,39 +43,39 @@ static const double dashed [] = struct _GcalWeekView { - GtkBox parent; + GtkBox parent; - GtkWidget *header; - GtkWidget *hours_bar; - GtkWidget *scrolled_window; - GtkWidget *week_grid; + GtkWidget *header; + GtkWidget *hours_bar; + GtkWidget *scrolled_window; + GtkWidget *week_grid; /* * first day of the week according to user locale, being * 0 for Sunday, 1 for Monday and so on */ - gint first_weekday; + gint first_weekday; /* * clock format from GNOME desktop settings */ - gboolean use_24h_format; + gboolean use_24h_format; /* property */ icaltimetype *date; GcalManager *manager; /* owned */ GcalWeatherService *weather_service; /* owned */ - guint scroll_grid_timeout_id; + guint scroll_grid_timeout_id; - gint clicked_cell; + gint clicked_cell; }; -static void schedule_position_scroll (GcalWeekView *self); +static void schedule_position_scroll (GcalWeekView *self); -static void gcal_view_interface_init (GcalViewInterface *iface); +static void gcal_view_interface_init (GcalViewInterface *iface); -static void gcal_data_model_subscriber_interface_init (ECalDataModelSubscriberInterface *iface); +static void gcal_data_model_subscriber_interface_init (ECalDataModelSubscriberInterface *iface); enum { diff --git a/src/views/gcal-year-view.c b/src/views/gcal-year-view.c index f18d1cc9..eaf0f607 100644 --- a/src/views/gcal-year-view.c +++ b/src/views/gcal-year-view.c @@ -35,90 +35,90 @@ typedef struct { /* month span from 0 to 11 */ - gint start_day, start_month; - gint end_day, end_month; - gint hovered_day, hovered_month; - gint dnd_day, dnd_month; + gint start_day, start_month; + gint end_day, end_month; + gint hovered_day, hovered_month; + gint dnd_day, dnd_month; } ButtonData; typedef struct { - gdouble box_side; - GdkPoint coordinates [12]; + gdouble box_side; + GdkPoint coordinates [12]; } GridData; struct _GcalYearView { - GtkBox parent; + GtkBox parent; /* composite, GtkBuilder's widgets */ - GtkWidget *navigator; - GtkWidget *sidebar; - GtkWidget *events_sidebar; - GtkWidget *navigator_stack; - GtkWidget *no_events_title; - GtkWidget *navigator_sidebar; - GtkWidget *scrolled_window; - GtkLabel *temp_label; /* unowned */ - GtkImage *weather_icon; /* unowned */ + GtkWidget *navigator; + GtkWidget *sidebar; + GtkWidget *events_sidebar; + GtkWidget *navigator_stack; + GtkWidget *no_events_title; + GtkWidget *navigator_sidebar; + GtkWidget *scrolled_window; + GtkLabel *temp_label; /* unowned */ + GtkImage *weather_icon; /* unowned */ - GtkWidget *popover; /* Popover for popover_mode */ + GtkWidget *popover; /* Popover for popover_mode */ /* manager singleton */ - GcalManager *manager; + GcalManager *manager; GcalWeatherService *weather_service; /* owned, nullable */ /* range shown on the sidebar */ - icaltimetype *start_selected_date; - icaltimetype *end_selected_date; + icaltimetype *start_selected_date; + icaltimetype *end_selected_date; /* geometry info */ - GridData *navigator_grid; - guint number_of_columns; - guint column_width; - guint row_height; - guint header_height; - guint sidebar_width; + GridData *navigator_grid; + guint number_of_columns; + guint column_width; + guint row_height; + guint header_height; + guint sidebar_width; /* state flags */ - gboolean popover_mode; - gboolean button_pressed; - ButtonData *selected_data; + gboolean popover_mode; + gboolean button_pressed; + ButtonData *selected_data; /** * first day of the week according to user locale, being * 0 for Sunday, 1 for Monday and so on */ - gint first_weekday; + gint first_weekday; /* first and last weeks of the year */ - guint first_week_of_year; - guint last_week_of_year; + guint first_week_of_year; + guint last_week_of_year; /* Storage for the accumulated scrolling */ - gdouble scroll_value; + gdouble scroll_value; /** * clock format from GNOME desktop settings */ - gboolean use_24h_format; + gboolean use_24h_format; /* show week numbers from GNOME Shell settings */ - GSettings *calendar_settings; - gboolean show_week_numbers; + GSettings *calendar_settings; + gboolean show_week_numbers; /* text direction factors */ - gint k; + gint k; /* date property */ - icaltimetype *date; + icaltimetype *date; /* * Array with the events at every month. Events * that span multiple months are added multiple * times to the array. */ - GPtrArray *events[12]; + GPtrArray *events[12]; }; enum { @@ -139,9 +139,10 @@ enum static guint signals[NUM_SIGNALS] = { 0, }; static gpointer year_view_parent_class = NULL; -static void gcal_view_interface_init (GcalViewInterface *iface); -static void gcal_data_model_subscriber_interface_init (ECalDataModelSubscriberInterface *iface); -static void update_weather (GcalYearView *self); +static void gcal_view_interface_init (GcalViewInterface *iface); +static void gcal_data_model_subscriber_interface_init (ECalDataModelSubscriberInterface *iface); +static void update_weather (GcalYearView *self); + G_DEFINE_TYPE_WITH_CODE (GcalYearView, gcal_year_view, GTK_TYPE_BOX, G_IMPLEMENT_INTERFACE (GCAL_TYPE_VIEW, gcal_view_interface_init) diff --git a/src/views/gcal-year-view.h b/src/views/gcal-year-view.h index da0d18e7..9cad185a 100644 --- a/src/views/gcal-year-view.h +++ b/src/views/gcal-year-view.h @@ -31,12 +31,14 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (GcalYearView, gcal_year_view, GCAL, YEAR_VIEW, GtkBox) -void gcal_year_view_set_first_weekday (GcalYearView *year_view, - gint nr_day); -void gcal_year_view_set_use_24h_format (GcalYearView *year_view, - gboolean use_24h_format); -void gcal_year_view_set_current_date (GcalYearView *year_view, - icaltimetype *current_date); +void gcal_year_view_set_first_weekday (GcalYearView *year_view, + gint nr_day); + +void gcal_year_view_set_use_24h_format (GcalYearView *year_view, + gboolean use_24h_format); + +void gcal_year_view_set_current_date (GcalYearView *year_view, + icaltimetype *current_date); G_END_DECLS