event-editor: Extract attendee summary row into a separate widget
Make the summary row reusable and filterable based on the attendee type. This gives us the possibility to have separate summaries for people/groups and resources/rooms. Part-of: <https://gitlab.gnome.org/GNOME/gnome-calendar/-/merge_requests/671>
This commit is contained in:
@@ -21,6 +21,8 @@ src/gui/event-editor/gcal-attendee-row.blp
|
|||||||
src/gui/event-editor/gcal-attendee-row.c
|
src/gui/event-editor/gcal-attendee-row.c
|
||||||
src/gui/event-editor/gcal-attendee-details-page.blp
|
src/gui/event-editor/gcal-attendee-details-page.blp
|
||||||
src/gui/event-editor/gcal-attendee-details-page.c
|
src/gui/event-editor/gcal-attendee-details-page.c
|
||||||
|
src/gui/event-editor/gcal-attendee-summary-row.blp
|
||||||
|
src/gui/event-editor/gcal-attendee-summary-row.c
|
||||||
src/gui/event-editor/gcal-attendees-section.blp
|
src/gui/event-editor/gcal-attendees-section.blp
|
||||||
src/gui/event-editor/gcal-attendees-section.c
|
src/gui/event-editor/gcal-attendees-section.c
|
||||||
src/gui/event-editor/gcal-date-chooser-row.blp
|
src/gui/event-editor/gcal-date-chooser-row.blp
|
||||||
|
|||||||
@@ -16,5 +16,6 @@
|
|||||||
<file compressed="true">gcal-attendees-section.ui</file>
|
<file compressed="true">gcal-attendees-section.ui</file>
|
||||||
<file compressed="true">gcal-attendee-row.ui</file>
|
<file compressed="true">gcal-attendee-row.ui</file>
|
||||||
<file compressed="true">gcal-attendee-details-page.ui</file>
|
<file compressed="true">gcal-attendee-details-page.ui</file>
|
||||||
|
<file compressed="true">gcal-attendee-summary-row.ui</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
</gresources>
|
</gresources>
|
||||||
|
|||||||
@@ -415,6 +415,15 @@ gcal_attendee_details_page_set_attendees (GcalAttendeeDetailsPage *self,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gcal_attendee_details_page_set_type_filter:
|
||||||
|
* @self: a #GcalAttendeeDetailsPage instance.
|
||||||
|
* @flags: flags of type #GcalEventAttendeeTypeFilterFlags.
|
||||||
|
*
|
||||||
|
* Sets the type of attendees to use as the base filter on the
|
||||||
|
* list of attendees. E.g. only people or only resources, or both
|
||||||
|
* are filtered before grouping by response is performed.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
gcal_attendee_details_page_set_type_filter (GcalAttendeeDetailsPage *self,
|
gcal_attendee_details_page_set_type_filter (GcalAttendeeDetailsPage *self,
|
||||||
GcalEventAttendeeTypeFilterFlags flags)
|
GcalEventAttendeeTypeFilterFlags flags)
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Gtk 4.0;
|
||||||
|
using Adw 1;
|
||||||
|
|
||||||
|
template $GcalAttendeeSummaryRow: Adw.ActionRow {
|
||||||
|
visible: bind template.filtered-list as <Gtk.FilterListModel>.n-items;
|
||||||
|
activatable-widget: open_details;
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"property",
|
||||||
|
]
|
||||||
|
|
||||||
|
[suffix]
|
||||||
|
Label {
|
||||||
|
valign: center;
|
||||||
|
label: bind template.filtered-list as <Gtk.FilterListModel>.n-items;
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"participants-count-label",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
[suffix]
|
||||||
|
Image open_details {
|
||||||
|
icon-name: "go-next-symbolic";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,359 @@
|
|||||||
|
/* gcal-attendee-summary-row.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 Alen Galinec <mind.on.warp@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gcal-attendee-summary-row.h"
|
||||||
|
#include "gcal-enum-types.h"
|
||||||
|
#include "gcal-enums.h"
|
||||||
|
#include "gcal-event-attendee.h"
|
||||||
|
#include "gio/gio.h"
|
||||||
|
#include "glib.h"
|
||||||
|
|
||||||
|
#include <adwaita.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <libintl.h>
|
||||||
|
|
||||||
|
struct _GcalAttendeeSummaryRow
|
||||||
|
{
|
||||||
|
AdwActionRow parent_instance;
|
||||||
|
|
||||||
|
GListStore *attendees;
|
||||||
|
GtkFilterListModel *filtered_attendees;
|
||||||
|
GtkCustomFilter *attendee_filter;
|
||||||
|
|
||||||
|
/* participation summary */
|
||||||
|
guint num_accepted;
|
||||||
|
guint num_declined;
|
||||||
|
guint num_tentative;
|
||||||
|
guint num_not_responded;
|
||||||
|
guint num_delegated;
|
||||||
|
|
||||||
|
GcalEventAttendeeTypeFilterFlags filter_flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_FINAL_TYPE (GcalAttendeeSummaryRow, gcal_attendee_summary_row, ADW_TYPE_ACTION_ROW)
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_ATTENDEES = 1,
|
||||||
|
PROP_FILTER_FLAGS,
|
||||||
|
PROP_FILTERED_LIST,
|
||||||
|
PROP_NUM_ACCEPTED,
|
||||||
|
PROP_NUM_DECLINED,
|
||||||
|
PROP_NUM_TENTATIVE,
|
||||||
|
PROP_NUM_DELEGATED,
|
||||||
|
PROP_NUM_UNKNOWN,
|
||||||
|
N_PROPS
|
||||||
|
};
|
||||||
|
|
||||||
|
static GParamSpec *properties[N_PROPS] = { NULL, };
|
||||||
|
|
||||||
|
/* Auxiliary methods */
|
||||||
|
|
||||||
|
static void
|
||||||
|
notify_summary_changed (GcalAttendeeSummaryRow *self)
|
||||||
|
{
|
||||||
|
for (guint i = 1; i < N_PROPS; ++i)
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), properties[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
custom_filter_func (GcalEventAttendee *attendee,
|
||||||
|
GcalAttendeeSummaryRow *self)
|
||||||
|
{
|
||||||
|
GcalEventAttendeeType attendee_type = gcal_event_attendee_get_attendee_type (attendee);
|
||||||
|
|
||||||
|
switch (self->filter_flags)
|
||||||
|
{
|
||||||
|
case GCAL_EVENT_ATTENDEE_TYPE_FILTER_PERSON:
|
||||||
|
return attendee_type == GCAL_EVENT_ATTENDEE_TYPE_INDIVIDUAL || attendee_type == GCAL_EVENT_ATTENDEE_TYPE_GROUP;
|
||||||
|
|
||||||
|
case GCAL_EVENT_ATTENDEE_TYPE_FILTER_RESOURCE:
|
||||||
|
return attendee_type == GCAL_EVENT_ATTENDEE_TYPE_ROOM || attendee_type == GCAL_EVENT_ATTENDEE_TYPE_RESOURCE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
concat_subtitle_part (GStrvBuilder *builder,
|
||||||
|
guint value,
|
||||||
|
const gchar *text)
|
||||||
|
{
|
||||||
|
if (value <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_strv_builder_take (builder, g_strdup_printf ("%d %s", value, text));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const gchar*
|
||||||
|
build_summary_subtitle (GcalAttendeeSummaryRow *self)
|
||||||
|
{
|
||||||
|
g_autoptr (GStrvBuilder) builder = g_strv_builder_new ();
|
||||||
|
g_auto (GStrv) parts = NULL;
|
||||||
|
|
||||||
|
concat_subtitle_part (builder, self->num_accepted, ngettext ("accepted", "accepted", self->num_accepted));
|
||||||
|
concat_subtitle_part (builder, self->num_tentative, ngettext ("maybe", "maybe", self->num_tentative));
|
||||||
|
concat_subtitle_part (builder, self->num_declined, ngettext ("declined", "declined", self->num_declined));
|
||||||
|
concat_subtitle_part (builder, self->num_delegated, ngettext ("delegated", "delegated", self->num_delegated));
|
||||||
|
concat_subtitle_part (builder, self->num_not_responded, ngettext ("not responded", "not responded", self->num_not_responded));
|
||||||
|
|
||||||
|
parts = g_strv_builder_end (builder);
|
||||||
|
|
||||||
|
return g_strjoinv (", ", parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup_filtered_attendees (GcalAttendeeSummaryRow *self,
|
||||||
|
GListModel *attendees)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GCAL_IS_ATTENDEE_SUMMARY_ROW (self));
|
||||||
|
|
||||||
|
g_list_store_remove_all (self->attendees);
|
||||||
|
self->num_accepted = 0;
|
||||||
|
self->num_declined = 0;
|
||||||
|
self->num_delegated = 0;
|
||||||
|
self->num_tentative = 0;
|
||||||
|
self->num_not_responded = 0;
|
||||||
|
|
||||||
|
if (attendees == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
guint n = g_list_model_get_n_items (attendees);
|
||||||
|
for (uint i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
GcalEventAttendee *attendee = g_list_model_get_item (attendees, i);
|
||||||
|
g_list_store_append (self->attendees, attendee);
|
||||||
|
|
||||||
|
/* this should be faster than going through self->filtered_attendees afterwards */
|
||||||
|
if (!custom_filter_func (attendee, self))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (gcal_event_attendee_get_part_status (attendee))
|
||||||
|
{
|
||||||
|
case GCAL_EVENT_ATTENDEE_PART_ACCEPTED:
|
||||||
|
self->num_accepted++;
|
||||||
|
break;
|
||||||
|
case GCAL_EVENT_ATTENDEE_PART_DECLINED:
|
||||||
|
self->num_declined++;
|
||||||
|
break;
|
||||||
|
case GCAL_EVENT_ATTENDEE_PART_DELEGATED:
|
||||||
|
self->num_delegated++;
|
||||||
|
break;
|
||||||
|
case GCAL_EVENT_ATTENDEE_PART_TENTATIVE:
|
||||||
|
self->num_tentative++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
self->num_not_responded++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_autofree const gchar *subtitle = build_summary_subtitle (self);
|
||||||
|
adw_action_row_set_subtitle (ADW_ACTION_ROW (self), subtitle);
|
||||||
|
|
||||||
|
notify_summary_changed (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
change_attendee_filter_type (GcalAttendeeSummaryRow *self,
|
||||||
|
GcalEventAttendeeTypeFilterFlags value)
|
||||||
|
{
|
||||||
|
self->filter_flags = value;
|
||||||
|
gtk_filter_changed (GTK_FILTER (self->attendee_filter), GTK_FILTER_CHANGE_DIFFERENT);
|
||||||
|
gtk_actionable_set_action_target (GTK_ACTIONABLE (self), "u", self->filter_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcal_attendee_summary_row_set_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GcalAttendeeSummaryRow *self = GCAL_ATTENDEE_SUMMARY_ROW (object);
|
||||||
|
|
||||||
|
switch (property_id)
|
||||||
|
{
|
||||||
|
case PROP_ATTENDEES:
|
||||||
|
setup_filtered_attendees (self, g_value_get_object (value));
|
||||||
|
break;
|
||||||
|
case PROP_FILTER_FLAGS:
|
||||||
|
change_attendee_filter_type (self, g_value_get_flags (value));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcal_attendee_summary_row_get_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GcalAttendeeSummaryRow *self = GCAL_ATTENDEE_SUMMARY_ROW (object);
|
||||||
|
|
||||||
|
switch (property_id)
|
||||||
|
{
|
||||||
|
case PROP_FILTER_FLAGS:
|
||||||
|
g_value_set_flags (value, self->filter_flags);
|
||||||
|
break;
|
||||||
|
case PROP_FILTERED_LIST:
|
||||||
|
g_value_set_object (value, self->filtered_attendees);
|
||||||
|
break;
|
||||||
|
case PROP_NUM_ACCEPTED:
|
||||||
|
g_value_set_uint (value, self->num_accepted);
|
||||||
|
break;
|
||||||
|
case PROP_NUM_DECLINED:
|
||||||
|
g_value_set_uint (value, self->num_declined);
|
||||||
|
break;
|
||||||
|
case PROP_NUM_DELEGATED:
|
||||||
|
g_value_set_uint (value, self->num_delegated);
|
||||||
|
break;
|
||||||
|
case PROP_NUM_TENTATIVE:
|
||||||
|
g_value_set_uint (value, self->num_tentative);
|
||||||
|
break;
|
||||||
|
case PROP_NUM_UNKNOWN:
|
||||||
|
g_value_set_uint (value, self->num_not_responded);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcal_attendee_summary_row_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GcalAttendeeSummaryRow *self = (GcalAttendeeSummaryRow *) object;
|
||||||
|
|
||||||
|
g_clear_pointer (&self->attendees, g_list_store_remove_all);
|
||||||
|
g_clear_object (&self->attendee_filter);
|
||||||
|
|
||||||
|
self->filtered_attendees = NULL;
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gcal_attendee_summary_row_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcal_attendee_summary_row_class_init (GcalAttendeeSummaryRowClass *klass)
|
||||||
|
{
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = gcal_attendee_summary_row_finalize;
|
||||||
|
object_class->set_property = gcal_attendee_summary_row_set_property;
|
||||||
|
object_class->get_property = gcal_attendee_summary_row_get_property;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GcalAttendeeSummaryRow:attendees:
|
||||||
|
*
|
||||||
|
* The unfiltered list of attendees.
|
||||||
|
*/
|
||||||
|
properties[PROP_ATTENDEES] =
|
||||||
|
g_param_spec_object ("attendees", NULL, NULL,
|
||||||
|
G_TYPE_LIST_MODEL,
|
||||||
|
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GcalAttendeeSummaryRow:filter-flags:
|
||||||
|
*
|
||||||
|
* The GCAL_TYPE_EVENT_ATTENDEE_TYPE_FILTER_FLAGS used to filter the attendees.
|
||||||
|
*/
|
||||||
|
properties[PROP_FILTER_FLAGS] =
|
||||||
|
g_param_spec_flags ("filter-flags", NULL, NULL,
|
||||||
|
GCAL_TYPE_EVENT_ATTENDEE_TYPE_FILTER_FLAGS, GCAL_EVENT_ATTENDEE_TYPE_FILTER_NONE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GcalAttendeeSummaryRow:filtered-list:
|
||||||
|
*
|
||||||
|
* The filtered list of attendees.
|
||||||
|
* Filtered by #GcalAttendeeSummaryRow:filter-type
|
||||||
|
*/
|
||||||
|
properties[PROP_FILTERED_LIST] =
|
||||||
|
g_param_spec_object ("filtered-list", NULL, NULL,
|
||||||
|
GTK_TYPE_FILTER_LIST_MODEL,
|
||||||
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GcalAttendeeSummaryRow:num-accepted:
|
||||||
|
*
|
||||||
|
* Gets the number of attendees who accepted.
|
||||||
|
*/
|
||||||
|
properties[PROP_NUM_ACCEPTED] =
|
||||||
|
g_param_spec_uint ("num-accepted", NULL, NULL,
|
||||||
|
0, G_MAXUINT, 0,
|
||||||
|
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GcalAttendeeSummaryRow:num-declined:
|
||||||
|
*
|
||||||
|
* Gets the number of attendees who declined.
|
||||||
|
*/
|
||||||
|
properties[PROP_NUM_DECLINED] =
|
||||||
|
g_param_spec_uint ("num-declined", NULL, NULL,
|
||||||
|
0, G_MAXUINT, 0,
|
||||||
|
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GcalAttendeeSummaryRow:num-tentative:
|
||||||
|
*
|
||||||
|
* Gets the number of attendees who "maybe" will attend.
|
||||||
|
*/
|
||||||
|
properties[PROP_NUM_TENTATIVE] =
|
||||||
|
g_param_spec_uint ("num-tentative", NULL, NULL,
|
||||||
|
0, G_MAXUINT, 0,
|
||||||
|
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GcalAttendeeSummaryRow:num-unknown:
|
||||||
|
*
|
||||||
|
* Gets the number of attendees with an unknown response.
|
||||||
|
*/
|
||||||
|
properties[PROP_NUM_UNKNOWN] =
|
||||||
|
g_param_spec_uint ("num-unknown", NULL, NULL,
|
||||||
|
0, G_MAXUINT, 0,
|
||||||
|
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GcalAttendeeSummaryRow:num-delegated:
|
||||||
|
*
|
||||||
|
* Gets the number of attendees who delegated their attendance to someone else.
|
||||||
|
*/
|
||||||
|
properties[PROP_NUM_DELEGATED] =
|
||||||
|
g_param_spec_uint ("num-delegated", NULL, NULL,
|
||||||
|
0, G_MAXUINT, 0,
|
||||||
|
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||||
|
|
||||||
|
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/ui/event-editor/gcal-attendee-summary-row.ui");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcal_attendee_summary_row_init (GcalAttendeeSummaryRow *instance)
|
||||||
|
{
|
||||||
|
instance->attendees = g_list_store_new (GCAL_TYPE_EVENT_ATTENDEE);
|
||||||
|
instance->attendee_filter = gtk_custom_filter_new ((GtkCustomFilterFunc) custom_filter_func, instance, NULL);
|
||||||
|
instance->filtered_attendees = gtk_filter_list_model_new (G_LIST_MODEL (instance->attendees), GTK_FILTER (instance->attendee_filter));
|
||||||
|
|
||||||
|
gtk_widget_init_template(GTK_WIDGET(instance));
|
||||||
|
|
||||||
|
gtk_actionable_set_action_name (GTK_ACTIONABLE (instance), "event-editor.show-attendees-detail-page");
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/* gcal-attendee-summary-row.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 Alen Galinec <mind.on.warp@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GCAL_ATTENDEE_SUMMARY_ROW_H
|
||||||
|
#define GCAL_ATTENDEE_SUMMARY_ROW_H
|
||||||
|
|
||||||
|
#include <adwaita.h>
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GCAL_TYPE_ATTENDEE_SUMMARY_ROW (gcal_attendee_summary_row_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (GcalAttendeeSummaryRow, gcal_attendee_summary_row, GCAL, ATTENDEE_SUMMARY_ROW, AdwActionRow)
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -23,30 +23,16 @@ template $GcalAttendeesSection: Gtk.Box {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
Adw.ActionRow summary_row {
|
$GcalAttendeeSummaryRow summary_row {
|
||||||
title: _("Participants");
|
title: _("Participants");
|
||||||
activatable-widget: open_details;
|
attendees: bind template.attendees;
|
||||||
activated => $on_participant_summary_row_activated_cb(template) not-swapped;
|
filter-flags: GCAL_EVENT_ATTENDEE_TYPE_FILTER_PERSON;
|
||||||
|
}
|
||||||
|
|
||||||
styles [
|
$GcalAttendeeSummaryRow {
|
||||||
"property",
|
title: _("Resources");
|
||||||
]
|
attendees: bind template.attendees;
|
||||||
|
filter-flags: GCAL_EVENT_ATTENDEE_TYPE_FILTER_RESOURCE;
|
||||||
[suffix]
|
|
||||||
Label {
|
|
||||||
valign: center;
|
|
||||||
label: bind template.num-participants as <string>;
|
|
||||||
tooltip-text: _("Number of participants");
|
|
||||||
|
|
||||||
styles [
|
|
||||||
"participants-count-label",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
[suffix]
|
|
||||||
Image open_details {
|
|
||||||
icon-name: "go-next-symbolic";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,13 +22,14 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
|
|
||||||
|
#include "gcal-attendee-summary-row.h"
|
||||||
#include "gcal-context.h"
|
#include "gcal-context.h"
|
||||||
#include "gcal-enums.h"
|
|
||||||
#include "gcal-event-attendee.h"
|
#include "gcal-event-attendee.h"
|
||||||
#include "gcal-event-editor-section.h"
|
#include "gcal-event-editor-section.h"
|
||||||
#include "gcal-event-organizer.h"
|
#include "gcal-event-organizer.h"
|
||||||
#include "gcal-event.h"
|
#include "gcal-event.h"
|
||||||
#include "gcal-utils.h"
|
#include "gcal-utils.h"
|
||||||
|
#include "glib-object.h"
|
||||||
|
|
||||||
struct _GcalAttendeesSection
|
struct _GcalAttendeesSection
|
||||||
{
|
{
|
||||||
@@ -40,12 +41,7 @@ struct _GcalAttendeesSection
|
|||||||
AdwActionRow *organizer_row;
|
AdwActionRow *organizer_row;
|
||||||
AdwActionRow *summary_row;
|
AdwActionRow *summary_row;
|
||||||
|
|
||||||
/* participation summary */
|
GListStore *attendees;
|
||||||
guint num_accepted;
|
|
||||||
guint num_declined;
|
|
||||||
guint num_tentative;
|
|
||||||
guint num_not_responded;
|
|
||||||
guint num_delegated;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void gcal_event_editor_section_init_iface (GcalEventEditorSectionInterface *iface);
|
static void gcal_event_editor_section_init_iface (GcalEventEditorSectionInterface *iface);
|
||||||
@@ -57,22 +53,10 @@ enum
|
|||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_CONTEXT,
|
PROP_CONTEXT,
|
||||||
PROP_NUM_ACCEPTED,
|
PROP_ATTENDEES,
|
||||||
PROP_NUM_DECLINED,
|
|
||||||
PROP_NUM_TENTATIVE,
|
|
||||||
PROP_NUM_DELEGATED,
|
|
||||||
PROP_NUM_UNKNOWN,
|
|
||||||
PROP_NUM_TOTAL,
|
|
||||||
N_PROPS
|
N_PROPS
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
SUMMARY_ROW_ACTIVATED,
|
|
||||||
N_SIGNALS,
|
|
||||||
};
|
|
||||||
|
|
||||||
static guint signals[N_SIGNALS] = { 0, };
|
|
||||||
static GParamSpec *properties[N_PROPS] = { NULL, };
|
static GParamSpec *properties[N_PROPS] = { NULL, };
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -84,50 +68,8 @@ reset_section (GcalAttendeesSection *self,
|
|||||||
|
|
||||||
g_set_object (&self->event, event);
|
g_set_object (&self->event, event);
|
||||||
|
|
||||||
|
g_list_store_remove_all (self->attendees);
|
||||||
adw_action_row_set_subtitle (self->organizer_row, NULL);
|
adw_action_row_set_subtitle (self->organizer_row, NULL);
|
||||||
adw_action_row_set_subtitle (self->summary_row, NULL);
|
|
||||||
|
|
||||||
self->num_accepted = 0;
|
|
||||||
self->num_declined = 0;
|
|
||||||
self->num_tentative = 0;
|
|
||||||
self->num_not_responded = 0;
|
|
||||||
self->num_delegated = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
concat_subtitle_part (GStrvBuilder *builder,
|
|
||||||
guint value,
|
|
||||||
const gchar *text)
|
|
||||||
{
|
|
||||||
if (value <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_strv_builder_take (builder, g_strdup_printf ("%d %s", value, text));
|
|
||||||
}
|
|
||||||
|
|
||||||
static gchar*
|
|
||||||
build_summary_subtitle (GcalAttendeesSection *self)
|
|
||||||
{
|
|
||||||
g_autoptr (GStrvBuilder) builder = g_strv_builder_new ();
|
|
||||||
|
|
||||||
concat_subtitle_part (builder, self->num_accepted, ngettext ("accepted", "accepted", self->num_accepted));
|
|
||||||
concat_subtitle_part (builder, self->num_tentative, ngettext ("maybe", "maybe", self->num_tentative));
|
|
||||||
concat_subtitle_part (builder, self->num_declined, ngettext ("declined", "declined", self->num_declined));
|
|
||||||
concat_subtitle_part (builder, self->num_delegated, ngettext ("delegated", "delegated", self->num_delegated));
|
|
||||||
concat_subtitle_part (builder, self->num_not_responded, ngettext ("not responded", "not responded", self->num_not_responded));
|
|
||||||
|
|
||||||
g_auto (GStrv) parts = g_strv_builder_end (builder);
|
|
||||||
|
|
||||||
gchar *result = g_strjoinv (", ", parts);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gcal_attendees_section_notify (GcalAttendeesSection *self)
|
|
||||||
{
|
|
||||||
for (guint i = 1; i < N_PROPS; ++i)
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), properties[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -157,37 +99,9 @@ gcal_attendees_section_set_event (GcalEventEditorSection *section,
|
|||||||
/* set attendees and summarize attendance status */
|
/* set attendees and summarize attendance status */
|
||||||
attendees = gcal_event_get_attendees (self->event);
|
attendees = gcal_event_get_attendees (self->event);
|
||||||
for (GSList *l = attendees; l != NULL; l = l->next)
|
for (GSList *l = attendees; l != NULL; l = l->next)
|
||||||
{
|
g_list_store_append (self->attendees, GCAL_EVENT_ATTENDEE (l->data));
|
||||||
g_autoptr (GcalEventAttendee) attendee = GCAL_EVENT_ATTENDEE (l->data);
|
|
||||||
|
|
||||||
switch (gcal_event_attendee_get_part_status (attendee))
|
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ATTENDEES]);
|
||||||
{
|
|
||||||
case GCAL_EVENT_ATTENDEE_PART_ACCEPTED:
|
|
||||||
self->num_accepted++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GCAL_EVENT_ATTENDEE_PART_DECLINED:
|
|
||||||
self->num_declined++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GCAL_EVENT_ATTENDEE_PART_TENTATIVE:
|
|
||||||
self->num_tentative++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GCAL_EVENT_ATTENDEE_PART_DELEGATED:
|
|
||||||
self->num_delegated++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
self->num_not_responded++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
adw_action_row_set_subtitle (self->summary_row, build_summary_subtitle (self));
|
|
||||||
|
|
||||||
/* notify properties changed */
|
|
||||||
gcal_attendees_section_notify (self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -211,21 +125,6 @@ gcal_event_editor_section_init_iface (GcalEventEditorSectionInterface *iface)
|
|||||||
iface->changed = gcal_attendees_section_changed;
|
iface->changed = gcal_attendees_section_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
|
||||||
gcal_attendees_section_get_num_participants (GcalAttendeesSection *self)
|
|
||||||
{
|
|
||||||
g_assert (GCAL_IS_ATTENDEES_SECTION (self));
|
|
||||||
|
|
||||||
return self->num_accepted + self->num_declined + self->num_tentative + self->num_delegated + self->num_not_responded;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_participant_summary_row_activated_cb (AdwActionRow *summary_row,
|
|
||||||
GcalAttendeesSection *self)
|
|
||||||
{
|
|
||||||
g_signal_emit (self, signals[SUMMARY_ROW_ACTIVATED], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gcal_attendees_section_get_property (GObject *object,
|
gcal_attendees_section_get_property (GObject *object,
|
||||||
guint property_id,
|
guint property_id,
|
||||||
@@ -240,28 +139,8 @@ gcal_attendees_section_get_property (GObject *object,
|
|||||||
g_value_set_object (value, self->context);
|
g_value_set_object (value, self->context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_NUM_ACCEPTED:
|
case PROP_ATTENDEES:
|
||||||
g_value_set_uint (value, self->num_accepted);
|
g_value_set_object (value, self->attendees);
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_NUM_DECLINED:
|
|
||||||
g_value_set_uint (value, self->num_declined);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_NUM_TENTATIVE:
|
|
||||||
g_value_set_uint (value, self->num_tentative);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_NUM_DELEGATED:
|
|
||||||
g_value_set_uint (value, self->num_delegated);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_NUM_UNKNOWN:
|
|
||||||
g_value_set_uint (value, self->num_not_responded);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_NUM_TOTAL:
|
|
||||||
g_value_set_uint (value, gcal_attendees_section_get_num_participants (self));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -296,6 +175,7 @@ gcal_attendees_section_finalize (GObject *object)
|
|||||||
|
|
||||||
g_clear_object (&self->context);
|
g_clear_object (&self->context);
|
||||||
g_clear_object (&self->event);
|
g_clear_object (&self->event);
|
||||||
|
g_clear_pointer (&self->attendees, g_list_store_remove_all);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gcal_attendees_section_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gcal_attendees_section_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@@ -303,6 +183,7 @@ gcal_attendees_section_finalize (GObject *object)
|
|||||||
static void
|
static void
|
||||||
gcal_attendees_section_init (GcalAttendeesSection *instance)
|
gcal_attendees_section_init (GcalAttendeesSection *instance)
|
||||||
{
|
{
|
||||||
|
instance->attendees = g_list_store_new (GCAL_TYPE_EVENT_ATTENDEE);
|
||||||
gtk_widget_init_template (GTK_WIDGET (instance));
|
gtk_widget_init_template (GTK_WIDGET (instance));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,6 +193,8 @@ gcal_attendees_section_class_init (GcalAttendeesSectionClass *klass)
|
|||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
|
|
||||||
|
g_type_ensure (GCAL_TYPE_ATTENDEE_SUMMARY_ROW);
|
||||||
|
|
||||||
object_class->finalize = gcal_attendees_section_finalize;
|
object_class->finalize = gcal_attendees_section_finalize;
|
||||||
object_class->get_property = gcal_attendees_section_get_property;
|
object_class->get_property = gcal_attendees_section_get_property;
|
||||||
object_class->set_property = gcal_attendees_section_set_property;
|
object_class->set_property = gcal_attendees_section_set_property;
|
||||||
@@ -326,87 +209,15 @@ gcal_attendees_section_class_init (GcalAttendeesSectionClass *klass)
|
|||||||
GCAL_TYPE_CONTEXT,
|
GCAL_TYPE_CONTEXT,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
/**
|
properties[PROP_ATTENDEES] =
|
||||||
* GcalAttendeesSection:num-accepted:
|
g_param_spec_object ("attendees", NULL, NULL,
|
||||||
*
|
G_TYPE_LIST_STORE,
|
||||||
* Gets the number of attendees who accepted.
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||||
*/
|
|
||||||
properties[PROP_NUM_ACCEPTED] =
|
|
||||||
g_param_spec_uint ("num-accepted", NULL, NULL,
|
|
||||||
0, G_MAXUINT, 0,
|
|
||||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GcalAttendeesSection:num-declined:
|
|
||||||
*
|
|
||||||
* Gets the number of attendees who declined.
|
|
||||||
*/
|
|
||||||
properties[PROP_NUM_DECLINED] =
|
|
||||||
g_param_spec_uint ("num-declined", NULL, NULL,
|
|
||||||
0, G_MAXUINT, 0,
|
|
||||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GcalAttendeesSection:num-tentative:
|
|
||||||
*
|
|
||||||
* Gets the number of attendees who "maybe" will attend.
|
|
||||||
*/
|
|
||||||
properties[PROP_NUM_TENTATIVE] =
|
|
||||||
g_param_spec_uint ("num-tentative", NULL, NULL,
|
|
||||||
0, G_MAXUINT, 0,
|
|
||||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GcalAttendeesSection:num-unknown:
|
|
||||||
*
|
|
||||||
* Gets the number of attendees with an unknown response.
|
|
||||||
*/
|
|
||||||
properties[PROP_NUM_UNKNOWN] =
|
|
||||||
g_param_spec_uint ("num-unknown", NULL, NULL,
|
|
||||||
0, G_MAXUINT, 0,
|
|
||||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GcalAttendeesSection: num-delegated:
|
|
||||||
*
|
|
||||||
* Gets the number of attendees who delegated their attendance to someone else.
|
|
||||||
*/
|
|
||||||
properties[PROP_NUM_DELEGATED] =
|
|
||||||
g_param_spec_uint ("num-delegated", NULL, NULL,
|
|
||||||
0, G_MAXUINT, 0,
|
|
||||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GcalAttendeesSection:num-participants:
|
|
||||||
*
|
|
||||||
* Gets the total number of attendees/participants.
|
|
||||||
*/
|
|
||||||
properties[PROP_NUM_TOTAL] =
|
|
||||||
g_param_spec_uint ("num-participants", NULL, NULL,
|
|
||||||
0, G_MAXUINT, 0,
|
|
||||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
|
||||||
|
|
||||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||||
|
|
||||||
/**
|
|
||||||
* GcalAttendeesSection::summary-row-activated:
|
|
||||||
*
|
|
||||||
* This signal is emitted when the summary row is activated.
|
|
||||||
*/
|
|
||||||
signals[SUMMARY_ROW_ACTIVATED] =
|
|
||||||
g_signal_new ("summary-row-activated",
|
|
||||||
GCAL_TYPE_ATTENDEES_SECTION,
|
|
||||||
G_SIGNAL_RUN_LAST,
|
|
||||||
0,
|
|
||||||
NULL, NULL,
|
|
||||||
NULL,
|
|
||||||
G_TYPE_NONE,
|
|
||||||
0);
|
|
||||||
|
|
||||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/ui/event-editor/gcal-attendees-section.ui");
|
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/ui/event-editor/gcal-attendees-section.ui");
|
||||||
|
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalAttendeesSection, organizer_row);
|
gtk_widget_class_bind_template_child (widget_class, GcalAttendeesSection, organizer_row);
|
||||||
gtk_widget_class_bind_template_child (widget_class, GcalAttendeesSection, summary_row);
|
gtk_widget_class_bind_template_child (widget_class, GcalAttendeesSection, summary_row);
|
||||||
|
|
||||||
gtk_widget_class_bind_template_callback (widget_class, on_participant_summary_row_activated_cb);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ template $GcalEventEditorDialog: Adw.Dialog {
|
|||||||
Adw.PreferencesGroup participants_group {
|
Adw.PreferencesGroup participants_group {
|
||||||
$GcalAttendeesSection attendees_section {
|
$GcalAttendeesSection attendees_section {
|
||||||
sensitive: bind template.writable;
|
sensitive: bind template.writable;
|
||||||
summary-row-activated => $on_attendees_summary_activated_cb(template) not-swapped;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -309,23 +309,6 @@ out:
|
|||||||
* Callbacks
|
* Callbacks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
|
||||||
on_attendees_summary_activated_cb (GcalAttendeesSection *section,
|
|
||||||
GcalEventEditorDialog *self)
|
|
||||||
{
|
|
||||||
g_autoptr (GSList) attendees = NULL;
|
|
||||||
|
|
||||||
g_assert (GCAL_IS_EVENT_EDITOR_DIALOG (self));
|
|
||||||
|
|
||||||
attendees = gcal_event_get_attendees (self->event);
|
|
||||||
|
|
||||||
gcal_attendee_details_page_set_attendees (GCAL_ATTENDEE_DETAILS_PAGE (self->attendee_details_page),
|
|
||||||
attendees);
|
|
||||||
|
|
||||||
adw_navigation_view_push (ADW_NAVIGATION_VIEW (self->nav_view),
|
|
||||||
ADW_NAVIGATION_PAGE (self->attendee_details_page));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_event_editor_save_action_activated_cb (GSimpleAction *action,
|
on_event_editor_save_action_activated_cb (GSimpleAction *action,
|
||||||
GVariant *param,
|
GVariant *param,
|
||||||
@@ -635,7 +618,6 @@ gcal_event_editor_dialog_class_init (GcalEventEditorDialogClass *klass)
|
|||||||
/* callbacks */
|
/* callbacks */
|
||||||
gtk_widget_class_bind_template_callback (widget_class, on_cancel_button_clicked_cb);
|
gtk_widget_class_bind_template_callback (widget_class, on_cancel_button_clicked_cb);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, on_delete_row_activated_cb);
|
gtk_widget_class_bind_template_callback (widget_class, on_delete_row_activated_cb);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, on_attendees_summary_activated_cb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -643,7 +625,7 @@ gcal_event_editor_dialog_init (GcalEventEditorDialog *self)
|
|||||||
{
|
{
|
||||||
static const GActionEntry actions[] = {
|
static const GActionEntry actions[] = {
|
||||||
{"save", on_event_editor_save_action_activated_cb },
|
{"save", on_event_editor_save_action_activated_cb },
|
||||||
{"show-attendees-detail-page", on_show_attendees_detail_page_action_activated_cb },
|
{"show-attendees-detail-page", on_show_attendees_detail_page_action_activated_cb, "u" },
|
||||||
};
|
};
|
||||||
|
|
||||||
gint i = 0;
|
gint i = 0;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ blueprints = custom_target(
|
|||||||
'gcal-attendees-section.blp',
|
'gcal-attendees-section.blp',
|
||||||
'gcal-attendee-row.blp',
|
'gcal-attendee-row.blp',
|
||||||
'gcal-attendee-details-page.blp',
|
'gcal-attendee-details-page.blp',
|
||||||
|
'gcal-attendee-summary-row.blp',
|
||||||
),
|
),
|
||||||
output: '.',
|
output: '.',
|
||||||
command: [
|
command: [
|
||||||
@@ -55,4 +56,5 @@ sources += files(
|
|||||||
'gcal-attendees-section.c',
|
'gcal-attendees-section.c',
|
||||||
'gcal-attendee-row.c',
|
'gcal-attendee-row.c',
|
||||||
'gcal-attendee-details-page.c',
|
'gcal-attendee-details-page.c',
|
||||||
|
'gcal-attendee-summary-row.c',
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user