Пример #1
0
static void
gcal_month_view_add (GtkContainer *container,
                     GtkWidget    *widget)
{
  GcalMonthViewPrivate *priv;
  GList *l;
  gint day;
  icaltimetype *date;

  g_return_if_fail (GCAL_IS_MONTH_VIEW (container));
  g_return_if_fail (GCAL_IS_EVENT_WIDGET (widget));
  g_return_if_fail (gtk_widget_get_parent (widget) == NULL);
  priv = GCAL_MONTH_VIEW (container)->priv;

  /* Check if it's already added for date */
  date = gcal_event_widget_get_date (GCAL_EVENT_WIDGET (widget));
  day = date->day + ( - priv->days_delay);
  g_free (date);

  for (l = priv->days[day]; l != NULL; l = l->next)
    {
      if (g_strcmp0 (
            gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (widget)),
            gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (l->data))) == 0)
        {
          g_warning ("Trying to add an event with the same uuid to the view");
          return;
        }
    }
  priv->days[day] = g_list_append (priv->days[day], widget);
  gtk_widget_set_parent (widget, GTK_WIDGET (container));
}
Пример #2
0
static void
gcal_event_widget_drag_begin (GtkWidget      *widget,
                              GdkDragContext *context)
{
  GcalEventWidget *self;
  cairo_surface_t *surface;
  GdkWindow *window;
  GdkDevice *device;
  gint x, y;
  GtkAllocation allocation;

  self = GCAL_EVENT_WIDGET (widget);
  window = gtk_widget_get_window (widget);
  device = gdk_drag_context_get_device (context);

  if (self->read_only)
    {
      gtk_drag_cancel (context);
      return;
    }

  /* Setup the drag n' drop icon */
  surface = get_dnd_icon (widget);

  gtk_drag_set_icon_surface (context, surface);

  /* reposition drag surface to the point the GCalEvent was */
  gtk_widget_get_allocation (widget, &allocation);
  gdk_window_get_device_position (window, device, &x, &y, NULL);
  gdk_drag_context_set_hotspot (context, x - allocation.x, y - allocation.y);

  g_clear_pointer (&surface, cairo_surface_destroy);
}
Пример #3
0
static void
gcal_event_widget_size_allocate (GtkWidget     *widget,
                                 GtkAllocation *allocation)
{
  GcalEventWidget *self;
  GtkAllocation old_allocation;

  self = GCAL_EVENT_WIDGET (widget);

  gtk_widget_get_allocation (widget, &old_allocation);

  if (gtk_widget_get_realized (widget))
    {
      gdk_window_move_resize (self->event_window,
                              allocation->x,
                              allocation->y,
                              allocation->width,
                              allocation->height);
    }

  GTK_WIDGET_CLASS (gcal_event_widget_parent_class)->size_allocate (widget, allocation);

  /*
   * Only after the child widgets (main grid, labels, etc) are allocated with the parent
   * class' allocation function, we can check if the current height is enough to hold the
   * vertical labels.
   */
  if (old_allocation.width != allocation->width || old_allocation.height != allocation->height)
    {
      if (self->orientation == GTK_ORIENTATION_HORIZONTAL || gcal_event_get_all_day (self->event))
        return;

      queue_set_vertical_labels (self, can_hold_vertical_labels_with_height (self, allocation->height));
    }
}
Пример #4
0
static void
gcal_event_widget_get_property (GObject      *object,
                                guint         property_id,
                                GValue       *value,
                                GParamSpec   *pspec)
{
  GcalEventWidget *self = GCAL_EVENT_WIDGET (object);

  switch (property_id)
    {
    case PROP_CONTEXT:
      g_value_set_object (value, self->context);
      break;

    case PROP_DATE_END:
      g_value_set_boxed (value, self->dt_end);
      break;

    case PROP_DATE_START:
      g_value_set_boxed (value, self->dt_start);
      break;

    case PROP_EVENT:
      g_value_set_object (value, self->event);
      break;

    case PROP_ORIENTATION:
      g_value_set_enum (value, self->orientation);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
    }
}
Пример #5
0
static void
gcal_event_widget_finalize (GObject *object)
{
  GcalEventWidget *self;

  self = GCAL_EVENT_WIDGET (object);

  /* disconnect signals */
  g_signal_handlers_disconnect_by_func (self->event, update_color, self);
  g_signal_handlers_disconnect_by_func (self->event, gtk_widget_queue_draw, self);

  /* releasing properties */
  g_clear_pointer (&self->css_class, g_free);
  g_clear_object (&self->event);
  g_clear_object (&self->context);

  /* remove timeouts */
  if (self->vertical_label_source_id > 0)
    {
      g_source_remove (self->vertical_label_source_id);
      self->vertical_label_source_id = 0;
    }

  G_OBJECT_CLASS (gcal_event_widget_parent_class)->finalize (object);
}
Пример #6
0
static gint
sidebar_sort_func (GtkListBoxRow *row1,
                   GtkListBoxRow *row2,
                   gpointer       user_data)
{
  GtkWidget *row1_child, *row2_child;
  gint result, row1_shift, row2_shift;

  row1_child = gtk_bin_get_child (GTK_BIN (row1));
  row2_child = gtk_bin_get_child (GTK_BIN (row2));
  row1_shift = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row1_child), "shift"));
  row2_shift = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row2_child), "shift"));

  result = row1_shift - row2_shift;
  if (result == 0)
    return gcal_event_widget_compare_for_single_day (GCAL_EVENT_WIDGET (row1_child), GCAL_EVENT_WIDGET (row2_child));

  return result;
}
Пример #7
0
GtkWidget*
gcal_event_widget_clone (GcalEventWidget *widget)
{
  GtkWidget *new_widget;

  new_widget = gcal_event_widget_new (widget->context, widget->event);
  gcal_event_widget_set_read_only (GCAL_EVENT_WIDGET (new_widget), widget->read_only);

  return new_widget;
}
Пример #8
0
static gboolean
gcal_event_widget_button_press_event (GtkWidget      *widget,
                                      GdkEventButton *event)
{
  GcalEventWidget *self;

  self = GCAL_EVENT_WIDGET (widget);
  self->button_pressed = TRUE;

  return GDK_EVENT_STOP;
}
Пример #9
0
static void
gcal_event_widget_unmap (GtkWidget *widget)
{
   GcalEventWidget *self;

  self = GCAL_EVENT_WIDGET (widget);

  GTK_WIDGET_CLASS (gcal_event_widget_parent_class)->unmap (widget);

  if (self->event_window)
    gdk_window_hide (self->event_window);
}
Пример #10
0
gint
gcal_compare_event_widget_by_date (gconstpointer a,
                                   gconstpointer b)
{
  /* negative value if a < b; zero if a = b; positive value if a > b. */
  GcalViewChild *a_child;
  GcalViewChild *b_child;
  GDateTime *a_date;
  GDateTime *b_date;

  gint comparison;

  a_child = (GcalViewChild*) a;
  b_child = (GcalViewChild*) b;

  a_date = gcal_event_get_date_start (gcal_event_widget_get_event (GCAL_EVENT_WIDGET (a_child->widget)));
  b_date = gcal_event_get_date_start (gcal_event_widget_get_event (GCAL_EVENT_WIDGET (b_child->widget)));

  comparison = g_date_time_compare (a_date, b_date);

  return comparison;
}
Пример #11
0
static void
gcal_event_widget_unrealize (GtkWidget *widget)
{
  GcalEventWidget *self;

  self = GCAL_EVENT_WIDGET (widget);

  if (self->event_window)
    {
      gtk_widget_unregister_window (widget, self->event_window);
      gdk_window_destroy (self->event_window);
      self->event_window = NULL;
    }

  GTK_WIDGET_CLASS (gcal_event_widget_parent_class)->unrealize (widget);
}
Пример #12
0
static GList*
gcal_year_view_get_children_by_uuid (GcalView    *view,
                                     const gchar *uuid)
{
  GcalYearViewPrivate *priv = GCAL_YEAR_VIEW (view)->priv;
  GList *children, *l, *result = NULL;

  children = gtk_container_get_children (GTK_CONTAINER (priv->events_sidebar));
  for (l = children; l != NULL; l = g_list_next (l))
    {
      GcalEventWidget *child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data)));
      if (child_widget != NULL && g_strcmp0 (uuid, gcal_event_widget_peek_uuid (child_widget)) == 0)
        result = g_list_append (result, child_widget);
    }
  g_list_free (children);

  return result;
}
Пример #13
0
static gboolean
gcal_event_widget_button_release_event (GtkWidget      *widget,
                                        GdkEventButton *event)
{
  GcalEventWidget *self;

  self = GCAL_EVENT_WIDGET (widget);

  if (self->button_pressed)
    {
      self->button_pressed = FALSE;
      g_signal_emit (widget, signals[ACTIVATE], 0);

      return GDK_EVENT_STOP;
    }

  return GDK_EVENT_PROPAGATE;
}
Пример #14
0
static void
gcal_event_widget_realize (GtkWidget *widget)
{
  GcalEventWidget *self;
  GdkWindowAttr attributes;
  GtkAllocation allocation;
  GdkWindow *parent_window;
  GdkCursor *pointer_cursor;
  gint attributes_mask;

  self = GCAL_EVENT_WIDGET (widget);
  gtk_widget_set_realized (widget, TRUE);

  parent_window = gtk_widget_get_parent_window (widget);
  gtk_widget_set_window (widget, parent_window);
  g_object_ref (parent_window);

  gtk_widget_get_allocation (widget, &allocation);

  attributes.window_type = GDK_WINDOW_CHILD;
  attributes.wclass = GDK_INPUT_ONLY;
  attributes.x = allocation.x;
  attributes.y = allocation.y;
  attributes.width = allocation.width;
  attributes.height = allocation.height;
  attributes.event_mask = gtk_widget_get_events (widget);
  attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
                            GDK_BUTTON_RELEASE_MASK |
                            GDK_BUTTON1_MOTION_MASK |
                            GDK_POINTER_MOTION_HINT_MASK |
                            GDK_POINTER_MOTION_MASK |
                            GDK_ENTER_NOTIFY_MASK |
                            GDK_LEAVE_NOTIFY_MASK |
                            GDK_SMOOTH_SCROLL_MASK |
                            GDK_SCROLL_MASK);
  attributes_mask = GDK_WA_X | GDK_WA_Y;

  self->event_window = gdk_window_new (parent_window, &attributes, attributes_mask);
  gtk_widget_register_window (widget, self->event_window);
  gdk_window_show (self->event_window);

  pointer_cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_HAND1);
  gdk_window_set_cursor (self->event_window, pointer_cursor);
}
Пример #15
0
static void
gcal_event_widget_set_property (GObject      *object,
                                guint         property_id,
                                const GValue *value,
                                GParamSpec   *pspec)
{
  GcalEventWidget *self = GCAL_EVENT_WIDGET (object);

  switch (property_id)
    {
    case PROP_CONTEXT:
      g_assert (self->context == NULL);
      self->context = g_value_dup_object (value);

      g_signal_connect_object (gcal_context_get_clock (self->context),
                               "minute-changed",
                               G_CALLBACK (update_color),
                               self,
                               G_CONNECT_SWAPPED);
      break;

    case PROP_DATE_END:
      gcal_event_widget_set_date_end (self, g_value_get_boxed (value));
      break;

    case PROP_DATE_START:
      gcal_event_widget_set_date_start (self, g_value_get_boxed (value));
      break;

    case PROP_EVENT:
      gcal_event_widget_set_event_internal (self, g_value_get_object (value));
      break;

    case PROP_ORIENTATION:
      self->orientation = g_value_get_enum (value);
      gtk_widget_set_visible (self->vertical_grid, self->orientation == GTK_ORIENTATION_VERTICAL);
      gcal_event_widget_update_style (self);
      g_object_notify (object, "orientation");
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
    }
}
Пример #16
0
static void
gcal_month_view_remove (GtkContainer *container,
                        GtkWidget    *widget)
{
  GcalMonthViewPrivate *priv;
  icaltimetype *date;
  gint day;

  g_return_if_fail (GCAL_IS_MONTH_VIEW (container));
  g_return_if_fail (gtk_widget_get_parent (widget) == GTK_WIDGET (container));
  priv = GCAL_MONTH_VIEW (container)->priv;

  date = gcal_event_widget_get_date (GCAL_EVENT_WIDGET (widget));
  day = date->day + ( - priv->days_delay);
  g_free (date);

  priv->days[day] = g_list_remove (priv->days[day], widget);
  gtk_widget_unparent (widget);
}
Пример #17
0
static void
gcal_month_view_remove_by_uuid (GcalView    *view,
                                const gchar *uuid)
{
  GcalMonthViewPrivate *priv;
  gint i;
  GList *l;

  g_return_if_fail (GCAL_IS_MONTH_VIEW (view));
  priv = GCAL_MONTH_VIEW (view)->priv;

  for (i = 0; i < 35; i++)
    {
      for (l = priv->days[i]; l != NULL; l = l->next)
        {
          const gchar* widget_uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (l->data));
          if (g_strcmp0 (uuid, widget_uuid) == 0)
            gtk_widget_destroy (GTK_WIDGET (l->data));
        }
    }
}
Пример #18
0
static void
gcal_year_view_component_changed (ECalDataModelSubscriber *subscriber,
                                  ECalClient              *client,
                                  ECalComponent           *comp)
{
  GcalYearViewPrivate *priv = GCAL_YEAR_VIEW (subscriber)->priv;
  GList *children, *l;
  gchar *uuid;

  uuid = get_uuid_from_component (e_client_get_source (E_CLIENT (client)), comp);
  children = gtk_container_get_children (GTK_CONTAINER (priv->events_sidebar));
  for (l = children; l != NULL; l = g_list_next (l))
    {
      GcalEventWidget *child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data)));
      if (child_widget != NULL && g_strcmp0 (uuid, gcal_event_widget_peek_uuid (child_widget)) == 0)
        gtk_widget_destroy (GTK_WIDGET (l->data));
    }
  g_list_free (children);
  g_free (uuid);

  gcal_year_view_component_added (subscriber, client, comp);
}
Пример #19
0
static void
gcal_year_view_component_removed (ECalDataModelSubscriber *subscriber,
                                  ECalClient              *client,
                                  const gchar             *uid,
                                  const gchar             *rid)
{
  GcalYearViewPrivate *priv = GCAL_YEAR_VIEW (subscriber)->priv;
  GList *children, *l;
  ESource *source;
  gchar *uuid;
  gboolean update_sidebar_needed = FALSE;

  source = e_client_get_source (E_CLIENT (client));
  if (rid != NULL)
    uuid = g_strdup_printf ("%s:%s:%s", e_source_get_uid (source), uid, rid);
  else
    uuid = g_strdup_printf ("%s:%s", e_source_get_uid (source), uid);

  children = gtk_container_get_children (GTK_CONTAINER (priv->events_sidebar));
  for (l = children; l != NULL; l = g_list_next (l))
    {
      GcalEventWidget *child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data)));
      if (child_widget != NULL && g_strcmp0 (uuid, gcal_event_widget_peek_uuid (child_widget)) == 0)
        {
          if (g_list_length (children) == 1)
            update_sidebar_needed = TRUE;
          gtk_widget_destroy (GTK_WIDGET (l->data));
        }
    }
  g_list_free (children);
  g_free (uuid);

  if (update_sidebar_needed)
    {
      update_no_events_page (GCAL_YEAR_VIEW (subscriber));
      gtk_stack_set_visible_child_name (GTK_STACK (priv->navigator_stack), "no-events");
    }
}
Пример #20
0
static void
update_sidebar_headers (GtkListBoxRow *row,
                        GtkListBoxRow *before,
                        gpointer user_data)
{
  GcalYearViewPrivate *priv;
  GtkWidget *row_child, *before_child = NULL, *row_header = NULL;
  const icaltimetype *row_date, *before_date = NULL;
  icaltimetype date;
  gint row_shift, before_shift =-1;

  priv = GCAL_YEAR_VIEW (user_data)->priv;
  row_child = gtk_bin_get_child (GTK_BIN (row));
  if (row_child == NULL)
    return;
  row_date = gcal_event_widget_peek_start_date (GCAL_EVENT_WIDGET (row_child));
  row_shift = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row_child), "shift"));
  if (before != NULL)
    {
      before_child = gtk_bin_get_child (GTK_BIN (before));
      before_date = gcal_event_widget_peek_start_date (GCAL_EVENT_WIDGET (before_child));
      before_shift = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (before_child), "shift"));
    }

  if (before_shift == -1 || before_shift != row_shift)
    {
      GtkWidget *label;
      gchar *label_str;

      row_header = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
      date = *(priv->start_selected_date);
      icaltime_adjust (&date, row_shift, 0, 0, 0);

      if (icaltime_compare_date (&date, priv->current_date) == 0)
        label_str = g_strdup (_("Today"));
      else
        label_str = g_strdup_printf ("%s %d", gcal_get_month_name (date.month  - 1), date.day);

      label = gtk_label_new (label_str);
      gtk_style_context_add_class (gtk_widget_get_style_context (label), "sidebar-header");
      g_object_set (label, "margin", 6, "halign", GTK_ALIGN_START, NULL);
      g_free (label_str);

      gtk_container_add (GTK_CONTAINER (row_header), label);
    }

  if (!gcal_event_widget_is_multiday (GCAL_EVENT_WIDGET (row_child)) &&
      !gcal_event_widget_get_all_day (GCAL_EVENT_WIDGET (row_child)) &&
      (before_date == NULL || before_date->hour != row_date->hour))
    {
      gchar *time;
      GtkWidget *label;

      if (priv->use_24h_format)
        time = g_strdup_printf ("%.2d:00", row_date->hour);
      else
        time = g_strdup_printf ("%.2d:00 %s", row_date->hour % 12, row_date->hour < 12 ? "AM" : "PM");

      label = gtk_label_new (time);
      gtk_style_context_add_class (gtk_widget_get_style_context (label), GTK_STYLE_CLASS_DIM_LABEL);
      g_object_set (label, "margin", 6, "halign", GTK_ALIGN_START, NULL);

      if (row_header == NULL)
        row_header = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);

      gtk_container_add (GTK_CONTAINER (row_header), label);
      gtk_container_add (GTK_CONTAINER (row_header), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));

      g_free (time);
    }

  if (row_header != NULL)
    gtk_widget_show_all (row_header);
  gtk_list_box_row_set_header (row, row_header);
}
Пример #21
0
static void
add_event_to_day_array (GcalYearView  *year_view,
                        GcalEventData *event_data,
                        GList        **days_widgets_array,
                        gint           days_span)
{
  GcalYearViewPrivate *priv;
  GtkWidget *child_widget;

  const icaltimetype *dt_start, *dt_end;
  icaltimetype date, second_date;

  gint i;
  gboolean child_widget_used = FALSE;

  priv = year_view->priv;
  child_widget = gcal_event_widget_new_from_data (event_data);
  gcal_event_widget_set_read_only (GCAL_EVENT_WIDGET (child_widget),
                                   gcal_manager_is_client_writable (priv->manager, event_data->source));

  dt_start = gcal_event_widget_peek_start_date (GCAL_EVENT_WIDGET (child_widget));
  dt_end = gcal_event_widget_peek_end_date (GCAL_EVENT_WIDGET (child_widget));

  /* normalize date on each new event */
  date = *(priv->start_selected_date);
  second_date = *(priv->start_selected_date);
  second_date.hour = 23;
  second_date.minute = 59;

  /* marking and cloning */
  for (i = 0; i < days_span; i++)
    {
      GtkWidget *cloned_child = child_widget;
      gint start_comparison, end_comparison;

      if (i != 0)
        {
          icaltime_adjust (&date, 1, 0, 0, 0);
          icaltime_adjust (&second_date, 1, 0, 0, 0);
        }

      start_comparison = icaltime_compare_date (dt_start, &date);
      if (start_comparison <= 0)
        {
          if (child_widget_used)
            cloned_child = gcal_event_widget_clone (GCAL_EVENT_WIDGET (child_widget));
          else
            child_widget_used = TRUE;
        }
      else
        {
          cloned_child = NULL;
        }

      if (cloned_child != NULL)
        {
          days_widgets_array[i] = g_list_insert_sorted (days_widgets_array[i],
                                                        cloned_child,
                                                        (GCompareFunc) gcal_event_widget_compare_for_single_day);

          end_comparison = icaltime_compare_date (&second_date, dt_end);
          /* XXX: hack ensuring allday events with end_date a day after */
          if (end_comparison == -1 && second_date.year == dt_end->year && dt_end->is_date == 1)
            end_comparison = 0;

          if (start_comparison < 0 && end_comparison < 0)
            gtk_style_context_add_class (gtk_widget_get_style_context (cloned_child), "slanted");
          else if (start_comparison < 0)
            gtk_style_context_add_class (gtk_widget_get_style_context (cloned_child), "slanted-start");
          else if (end_comparison < 0)
            gtk_style_context_add_class (gtk_widget_get_style_context (cloned_child), "slanted-end");

          if (end_comparison == 0)
            break;
        }
    }
}