コード例 #1
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));
    }
}
コード例 #2
0
static void
gcal_event_widget_set_event_internal (GcalEventWidget *self,
                                      GcalEvent       *event)
{
  g_autofree gchar *hour_str = NULL;

  /*
   * This function is called only once, since the property is
   * set as CONSTRUCT_ONLY. Any other attempt to set an event
   * will be ignored.
   *
   * Because of that condition, we don't really have to care about
   * disconnecting functions or cleaning up the previous event.
   */

  /* The event spawns with a floating reference, and we take it's ownership */
  g_set_object (&self->event, event);

  /*
   * Initially, the widget's start and end dates are the same
   * of the event's ones. We may change it afterwards.
   */
  gcal_event_widget_set_date_start (self, gcal_event_get_date_start (event));
  gcal_event_widget_set_date_end (self, gcal_event_get_date_end (event));

  /* Update color */
  update_color (self);

  g_signal_connect_swapped (event,
                            "notify::color",
                            G_CALLBACK (update_color),
                            self);

  g_signal_connect_swapped (event,
                            "notify::summary",
                            G_CALLBACK (gtk_widget_queue_draw),
                            self);

  /* Tooltip */
  gcal_event_widget_set_event_tooltip (self, event);

  /* Hour label */
  hour_str = get_hour_label (self);

  gtk_widget_set_visible (self->hour_label, !gcal_event_get_all_day (event));
  gtk_label_set_label (GTK_LABEL (self->hour_label), hour_str);

  /* Summary label */
  g_object_bind_property (event,
                          "summary",
                          self->summary_label,
                          "label",
                          G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
}
コード例 #3
0
static gboolean
get_result_metas_cb (GcalShellSearchProvider  *search_provider,
                     GDBusMethodInvocation    *invocation,
                     gchar                   **results,
                     GcalShellSearchProvider2 *skel)
{
  GcalShellSearchProviderPrivate *priv;
  GDateTime *local_datetime;
  GVariantBuilder abuilder, builder;
  GVariant *icon_variant;
  GcalEvent *event;
  GdkPixbuf *gicon;
  gchar *uuid, *desc;
  gchar *start_date;
  gint i;

  priv = search_provider->priv;

  g_variant_builder_init (&abuilder, G_VARIANT_TYPE ("aa{sv}"));
  for (i = 0; i < g_strv_length (results); i++)
    {
      uuid = results[i];
      event = g_hash_table_lookup (priv->events, uuid);

      g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
      g_variant_builder_add (&builder, "{sv}", "id", g_variant_new_string (uuid));
      g_variant_builder_add (&builder, "{sv}", "name", g_variant_new_string (gcal_event_get_summary (event)));

      gicon = get_circle_pixbuf_from_color (gcal_event_get_color (event), 128);
      icon_variant = g_icon_serialize (G_ICON (gicon));
      g_variant_builder_add (&builder, "{sv}", "icon", icon_variant);
      g_object_unref (gicon);
      g_variant_unref (icon_variant);

      local_datetime = g_date_time_to_local (gcal_event_get_date_start (event));

      /* FIXME: respect 24h time format */
      start_date = g_date_time_format (local_datetime, gcal_event_get_all_day (event) ? "%x" : "%c");

      if (gcal_event_get_location (event))
        desc = g_strconcat (start_date, ". ", gcal_event_get_location (event), NULL);
      else
        desc = g_strdup (start_date);

      g_variant_builder_add (&builder, "{sv}", "description", g_variant_new_string (desc));
      g_variant_builder_add_value (&abuilder, g_variant_builder_end (&builder));
    }
  g_dbus_method_invocation_return_value (invocation, g_variant_new ("(aa{sv})", &abuilder));

  return TRUE;
}
コード例 #4
0
/* ECalDataModelSubscriber implementation */
static void
gcal_week_view_component_added (ECalDataModelSubscriber *subscriber,
                                ECalClient              *client,
                                ECalComponent           *comp)
{
  GcalWeekView *self = GCAL_WEEK_VIEW (subscriber);

  GcalEvent *event;

  GCAL_ENTRY;

  event = gcal_event_new (e_client_get_source (E_CLIENT (client)), comp, NULL);

  if (gcal_event_is_multiday (event) || gcal_event_get_all_day (event))
    gcal_week_header_add_event (GCAL_WEEK_HEADER (self->header), event);
  else
    gcal_week_grid_add_event (GCAL_WEEK_GRID (self->week_grid), event);

  GCAL_EXIT;
}
コード例 #5
0
static void
gcal_event_widget_set_event_tooltip (GcalEventWidget *self,
                                     GcalEvent       *event)
{
  g_autoptr (GDateTime) tooltip_start, tooltip_end;
  g_autofree gchar *start, *end, *escaped_summary;
  GString *tooltip_mesg;
  gboolean allday, multiday, is_ltr;
  guint description_len;

  tooltip_mesg = g_string_new (NULL);
  escaped_summary = g_markup_escape_text (gcal_event_get_summary (event), -1);
  g_string_append_printf (tooltip_mesg, "<b>%s</b>", escaped_summary);

  allday = gcal_event_get_all_day (event);
  multiday = gcal_event_is_multiday (event);

  is_ltr = gtk_widget_get_direction (GTK_WIDGET (self)) != GTK_TEXT_DIR_RTL;

  if (allday)
    {
      /* All day events span from [ start, end - 1 day ] */
      tooltip_start = g_date_time_ref (gcal_event_get_date_start (event));
      tooltip_end = g_date_time_add_days (gcal_event_get_date_end (event), -1);

      if (multiday)
        {
          start = g_date_time_format (tooltip_start, "%x");
          end = g_date_time_format (tooltip_end, "%x");
        }
      else
        {
          start = g_date_time_format (tooltip_start, "%x");
          end = NULL;
        }
    }
  else
    {
      tooltip_start = g_date_time_to_local (gcal_event_get_date_start (event));
      tooltip_end = g_date_time_to_local (gcal_event_get_date_end (event));

      if (multiday)
        {
          if (self->clock_format_24h)
            {
              if (is_ltr)
                {
                  start = g_date_time_format (tooltip_start, "%x %R");
                  end = g_date_time_format (tooltip_end, "%x %R");
                }
              else
                {
                  start = g_date_time_format (tooltip_start, "%R %x");
                  end = g_date_time_format (tooltip_end, "%R %x");
                }
            }
          else
            {
              if (is_ltr)
                {
                  start = g_date_time_format (tooltip_start, "%x %I:%M %P");
                  end = g_date_time_format (tooltip_end, "%x %I:%M %P");
                }
              else
                {
                  start = g_date_time_format (tooltip_start, "%P %M:%I %x");
                  end = g_date_time_format (tooltip_end, "%P %M:%I %x");
                }
            }
        }
      else
        {
          if (self->clock_format_24h)
            {
              if (is_ltr)
                {
                  start = g_date_time_format (tooltip_start, "%x, %R");
                  end = g_date_time_format (tooltip_end, "%R");
                }
              else
                {
                  start = g_date_time_format (tooltip_start, "%R ,%x");
                  end = g_date_time_format (tooltip_end, "%R");
                }
            }
          else
            {
              if (is_ltr)
                {
                  start = g_date_time_format (tooltip_start, "%x, %I:%M %P");
                  end = g_date_time_format (tooltip_end, "%I:%M %P");
                }
              else
                {
                  start = g_date_time_format (tooltip_start, "%P %M:%I ,%x");
                  end = g_date_time_format (tooltip_end, "%P %M:%I");
                }
            }
        }
    }

  if (allday && !multiday)
    {
      g_string_append_printf (tooltip_mesg, "\n%s", start);
    }
  else
    {
      g_string_append_printf (tooltip_mesg,
                              "\n%s - %s",
                              is_ltr ? start : end,
                              is_ltr ? end : start);
    }

  /* Append event location */
  if (g_utf8_strlen (gcal_event_get_location (event), -1) > 0)
    {
      g_autofree gchar *escaped_location;

      escaped_location = g_markup_escape_text (gcal_event_get_location (event), -1);

      g_string_append (tooltip_mesg, "\n\n");

      /* Translators: %s is the location of the event (e.g. "Downtown, 3rd Avenue") */
      g_string_append_printf (tooltip_mesg, _("At %s"), escaped_location);
    }

  description_len = g_utf8_strlen (gcal_event_get_description (event), -1);

  /* Truncate long descriptions at a white space and ellipsize */
  if (description_len > 0)
    {
      g_autofree gchar *escaped_description;
      GString *tooltip_desc;

      tooltip_desc = g_string_new (gcal_event_get_description (event));

      /* If the description is larger than DESC_MAX_CHAR, ellipsize it */
      if (description_len > DESC_MAX_CHAR)
        {
          g_string_truncate (tooltip_desc, DESC_MAX_CHAR - 1);
          g_string_append (tooltip_desc, "…");
        }

      escaped_description = g_markup_escape_text (tooltip_desc->str, -1);

      g_string_append_printf (tooltip_mesg, "\n\n%s", escaped_description);

      g_string_free (tooltip_desc, TRUE);
    }

  gtk_widget_set_tooltip_markup (GTK_WIDGET (self), tooltip_mesg->str);

  g_string_free (tooltip_mesg, TRUE);
}
コード例 #6
0
static void
gcal_event_widget_update_style (GcalEventWidget *self)
{
  GtkStyleContext *context;
  gboolean slanted_start;
  gboolean slanted_end;
  gboolean timed;

  context = gtk_widget_get_style_context (GTK_WIDGET (self));
  slanted_start = FALSE;
  slanted_end = FALSE;

  /* Clear previous style classes */
  gtk_style_context_remove_class (context, "slanted");
  gtk_style_context_remove_class (context, "slanted-start");
  gtk_style_context_remove_class (context, "slanted-end");

  /*
   * If the event's dates differs from the widget's dates,
   * add a slanted edge class at the widget.
   */

  if (self->dt_start)
    slanted_start = g_date_time_compare (gcal_event_get_date_start (self->event), self->dt_start) != 0;

  if (self->dt_end)
    slanted_end = g_date_time_compare (gcal_event_get_date_end (self->event), self->dt_end) != 0;

  if (slanted_start && slanted_end)
    gtk_style_context_add_class (context, "slanted");
  else if (slanted_start)
    gtk_style_context_add_class (context, "slanted-start");
  else if (slanted_end)
    gtk_style_context_add_class (context, "slanted-end");

  /* TODO: adjust margins based on the CSS gradients sizes, not hardcoded */
  gtk_widget_set_margin_start (self->stack, slanted_start ? 20 : 4);
  gtk_widget_set_margin_end (self->stack, slanted_end ? 20 : 4);

  /* Add style classes for orientation selectors */
  if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
    {
      gtk_style_context_add_class (context, "horizontal");
      gtk_style_context_remove_class (context, "vertical");
    }
  else
    {
      gtk_style_context_add_class (context, "vertical");
      gtk_style_context_remove_class (context, "horizontal");
    }

  /*
   * If the event is a timed, single-day event, draw it differently
   * from all-day or multi-day events.
   */
  timed = !gcal_event_get_all_day (self->event) && !gcal_event_is_multiday (self->event);

  gtk_widget_set_visible (self->color_box, timed);

  if (timed)
    {
      GtkStyleContext *context;

      context = gtk_widget_get_style_context (GTK_WIDGET (self));
      gtk_style_context_add_class (context, "timed");

      if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
        {
          gtk_widget_set_margin_start (self->stack, 0);
          gtk_widget_set_margin_end (self->stack, 2);
        }
      else
        {
          gtk_widget_set_visible (self->color_box, FALSE);
        }
    }
}