[california/wip/725786-edit-recurring] Initialize controls with RRULE parameters
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california/wip/725786-edit-recurring] Initialize controls with RRULE parameters
- Date: Fri, 11 Jul 2014 01:08:13 +0000 (UTC)
commit ca50b1bf75568a715d72478afe3addc4364a9706
Author: Jim Nelson <jim yorba org>
Date: Thu Jul 10 18:07:33 2014 -0700
Initialize controls with RRULE parameters
This introduces a notion of a master Instance that can be fetched
from the CalendarSource
src/backing/backing-calendar-source.vala | 17 +++
src/backing/backing-error.vala | 6 +-
src/backing/eds/backing-eds-calendar-source.vala | 16 +++
src/component/component-date-time.vala | 50 ++++---
src/component/component-event.vala | 16 +--
src/component/component-instance.vala | 3 +-
src/component/component-recurrence-rule.vala | 21 +++-
src/host/host-create-update-recurring.vala | 155 ++++++++++++++++++++--
src/host/host-main-window.vala | 5 +-
src/host/host-quick-create-event.vala | 16 +-
src/host/host-show-event.vala | 4 +-
src/rc/create-update-recurring.ui | 9 +-
12 files changed, 257 insertions(+), 61 deletions(-)
---
diff --git a/src/backing/backing-calendar-source.vala b/src/backing/backing-calendar-source.vala
index 4e6589b..895f7cf 100644
--- a/src/backing/backing-calendar-source.vala
+++ b/src/backing/backing-calendar-source.vala
@@ -95,6 +95,23 @@ public abstract class CalendarSource : Source {
AffectedInstances affected, Cancellable? cancellable = null) throws Error;
/**
+ * Fetches the master component of an { link Component.Instance}.
+ *
+ * If an Instance is recurring, { link CalendarSourceSubscription} produces individual instances
+ * of those recurrences (which therefore lack the rules and information that produce them).
+ * This call allows for the original (or master) component to be retrieved.
+ *
+ * If the instance is not recurring, the returned Instance will be identical (or near-identical)
+ * to the one produced by CalendarSourceSubscription.
+ *
+ * @see Component.Instance.is_recurring_instance
+ * @throws An Error if the { link Component.UID} is unknown to the { link CalendarSource},
+ * as well as for the sundry I/O errors and such.
+ */
+ public abstract async Component.Instance fetch_master_component_async(Component.UID uid,
+ Cancellable? cancellable = null) throws Error;
+
+ /**
* Imports a { link Component.iCalendar} into the { link CalendarSource}.
*/
public abstract async void import_icalendar_async(Component.iCalendar ical, Cancellable? cancellable =
null)
diff --git a/src/backing/backing-error.vala b/src/backing/backing-error.vala
index 0857010..3f30d3a 100644
--- a/src/backing/backing-error.vala
+++ b/src/backing/backing-error.vala
@@ -22,7 +22,11 @@ public errordomain BackingError {
/**
* The method or object is unavailable due to a state change (not open or removed).
*/
- UNAVAILABLE
+ UNAVAILABLE,
+ /**
+ * The object or identifier is not recognized.
+ */
+ UNKNOWN
}
}
diff --git a/src/backing/eds/backing-eds-calendar-source.vala
b/src/backing/eds/backing-eds-calendar-source.vala
index 440327e..eb1e2a9 100644
--- a/src/backing/eds/backing-eds-calendar-source.vala
+++ b/src/backing/eds/backing-eds-calendar-source.vala
@@ -226,6 +226,22 @@ internal class EdsCalendarSource : CalendarSource {
yield client.modify_object(ical_component, E.CalObjModType.THIS, cancellable);
}
+ public override async Component.Instance fetch_master_component_async(Component.UID uid,
+ Cancellable? cancellable = null) throws Error {
+ // get the master instance for this UID
+ iCal.icalcomponent ical_component;
+ yield client.get_object(uid.value, null, cancellable, out ical_component);
+
+ // convert into an Instance and return
+ Component.Instance? instance = Component.Instance.convert(this, ical_component);
+ if (instance == null) {
+ throw new BackingError.UNKNOWN("UID %s is unknown to calendar %s", uid.to_string(),
+ to_string());
+ }
+
+ return instance;
+ }
+
public override async void import_icalendar_async(Component.iCalendar ical, Cancellable? cancellable =
null)
throws Error {
check_open();
diff --git a/src/component/component-date-time.vala b/src/component/component-date-time.vala
index d52bd00..aba1c9f 100644
--- a/src/component/component-date-time.vala
+++ b/src/component/component-date-time.vala
@@ -126,39 +126,45 @@ public class DateTime : BaseObject, Gee.Hashable<DateTime>, Gee.Comparable<DateT
/**
* Creates a new { link DateTime} for a component's RRULE UNTIL property.
+ *
+ * Strict will attempt to adhere to the MUSTs and SHALLs present in the iCal specification
+ * regarding RRULE's UNTIL property. See [[https://tools.ietf.org/html/rfc5545#section-3.3.10]]
*/
- public DateTime.rrule_until(iCal.icalrecurrencetype rrule, DateTime dtstart) throws ComponentError {
+ public DateTime.rrule_until(iCal.icalrecurrencetype rrule, DateTime dtstart, bool strict)
+ throws ComponentError {
if (iCal.icaltime_is_null_time(rrule.until) != 0)
throw new ComponentError.INVALID("DATE-TIME for RRULE UNTIL is null time");
- if (iCal.icaltime_is_valid_time(rrule.until) != 0)
+ if (iCal.icaltime_is_valid_time(rrule.until) == 0)
throw new ComponentError.INVALID("DATE-TIME for RRULE UNTIL is invalid");
bool until_is_date = (iCal.icaltime_is_date(rrule.until) != 0);
bool until_is_utc = (iCal.icaltime_is_utc(rrule.until) != 0);
- // "The value of the UNTIL rule part MUST have the same value type as the 'DTSTART'
- // property."
- if (dtstart.is_date != until_is_date)
- throw new ComponentError.INVALID("RRULE UNTIL and DTSTART must be of same type
(DATE/DATE-TIME)");
-
- // "If the 'DTSTART' property is specified as a date with local time, then the UNTIL rule
- // part MUST also be specified as a date with local time."
- if (dtstart.is_utc != until_is_utc)
- throw new ComponentError.INVALID("RRULE UNTIL and DTSTART must be of same time type
(UTC/local)");
-
- // "if the 'DTSTART' property is specified as a date with UTC time or a date with local time
- // and a time zone reference, then the UNTIL rule part MUST be specified as a date with
- // UTC time."
- if (dtstart.is_date || (!dtstart.is_utc && dtstart.zone != null)) {
- if (!until_is_utc)
- throw new ComponentError.INVALID("RRULE UNTIL must be UTC for DTSTART DATE or w/ time zone");
+ if (strict) {
+ // "The value of the UNTIL rule part MUST have the same value type as the 'DTSTART'
+ // property."
+ if (dtstart.is_date != until_is_date)
+ throw new ComponentError.INVALID("RRULE UNTIL and DTSTART must be of same type
(DATE/DATE-TIME)");
+
+ // "If the 'DTSTART' property is specified as a date with local time, then the UNTIL rule
+ // part MUST also be specified as a date with local time."
+ if (dtstart.is_utc != until_is_utc)
+ throw new ComponentError.INVALID("RRULE UNTIL and DTSTART must be of same time type
(UTC/local)");
+
+ // "if the 'DTSTART' property is specified as a date with UTC time or a date with local time
+ // and a time zone reference, then the UNTIL rule part MUST be specified as a date with
+ // UTC time."
+ if (dtstart.is_date || (!dtstart.is_utc && dtstart.zone != null)) {
+ if (!until_is_utc)
+ throw new ComponentError.INVALID("RRULE UNTIL must be UTC for DTSTART DATE or w/ time
zone");
+ }
+
+ // "If specified as a DATE-TIME value, then it MUST be specified in a UTC time format."
+ if (!until_is_date && !until_is_utc)
+ throw new ComponentError.INVALID("RRULE DATE-TIME UNTIL must be UTC");
}
- // "If specified as a DATE-TIME value, then it MUST be specified in a UTC time format."
- if (!until_is_date && !until_is_utc)
- throw new ComponentError.INVALID("RRULE DATE-TIME UNTIL must be UTC");
-
kind = iCal.icalproperty_kind.RRULE_PROPERTY;
dt = rrule.until;
zone = (!until_is_date || until_is_utc) ? Calendar.OlsonZone.utc : null;
diff --git a/src/component/component-event.vala b/src/component/component-event.vala
index 9a14b3d..ebae855 100644
--- a/src/component/component-event.vala
+++ b/src/component/component-event.vala
@@ -163,7 +163,7 @@ public class Event : Instance, Gee.Comparable<Event> {
}
try {
- make_recurring(new RecurrenceRule.from_ical(ical_component));
+ make_recurring(new RecurrenceRule.from_ical(ical_component, false));
} catch (ComponentError comperr) {
// ignored; generally means no RRULE in component
}
@@ -438,12 +438,10 @@ public class Event : Instance, Gee.Comparable<Event> {
if (compare != 0)
return compare;
- // if recurring, go by sequence number, as the UID and RID are the same for all instances
- if (is_recurring) {
- compare = sequence - other.sequence;
- if (compare != 0)
- return compare;
- }
+ // use sequence number if available
+ compare = sequence - other.sequence;
+ if (compare != 0)
+ return compare;
// stabilize with UIDs
return uid.compare_to(other.uid);
@@ -457,10 +455,10 @@ public class Event : Instance, Gee.Comparable<Event> {
if (this == other_event)
return true;
- if (is_recurring != other_event.is_recurring)
+ if (is_recurring_instance != other_event.is_recurring_instance)
return false;
- if (is_recurring && !rid.equal_to(other_event.rid))
+ if (is_recurring_instance && !rid.equal_to(other_event.rid))
return false;
if (sequence != other_event.sequence)
diff --git a/src/component/component-instance.vala b/src/component/component-instance.vala
index 56c86ab..a515ade 100644
--- a/src/component/component-instance.vala
+++ b/src/component/component-instance.vala
@@ -71,8 +71,9 @@ public abstract class Instance : BaseObject, Gee.Hashable<Instance> {
* Returns true if the { link Recurrable} is in fact a recurring instance.
*
* @see rid
+ * @see Backing.CalendarSource.fetch_master_component_async
*/
- public bool is_recurring { get { return rid != null; } }
+ public bool is_recurring_instance { get { return rid != null; } }
/**
* The SEQUENCE of a VEVENT, VTODO, or VJOURNAL.
diff --git a/src/component/component-recurrence-rule.vala b/src/component/component-recurrence-rule.vala
index 289a4b3..ab3d624 100644
--- a/src/component/component-recurrence-rule.vala
+++ b/src/component/component-recurrence-rule.vala
@@ -137,7 +137,7 @@ public class RecurrenceRule : BaseObject {
this.freq = freq;
}
- internal RecurrenceRule.from_ical(iCal.icalcomponent ical_component) throws Error {
+ internal RecurrenceRule.from_ical(iCal.icalcomponent ical_component, bool strict) throws Error {
// need DTSTART for timezone purposes
DateTime dtstart = new DateTime(ical_component, iCal.icalproperty_kind.DTSTART_PROPERTY);
@@ -155,7 +155,7 @@ public class RecurrenceRule : BaseObject {
if (rrule.count > 0) {
set_recurrence_count(rrule.count);
} else {
- Component.DateTime date_time = new DateTime.rrule_until(rrule, dtstart);
+ Component.DateTime date_time = new DateTime.rrule_until(rrule, dtstart, strict);
if (date_time.is_date)
set_recurrence_end_date(date_time.to_date());
else
@@ -253,6 +253,23 @@ public class RecurrenceRule : BaseObject {
}
/**
+ * Returns the UNTIL property as a { link Calendar.Date}.
+ *
+ * If { link until_exact_time} is set, only the Date portion is returned.
+ *
+ * @returns null if neither { link until_date} or until_exact_time is set.
+ */
+ public Calendar.Date? get_recurrence_end_date() {
+ if (until_date != null)
+ return until_date;
+
+ if (until_exact_time != null)
+ return new Calendar.Date.from_exact_time(until_exact_time);
+
+ return null;
+ }
+
+ /**
* Sets the { link count} property.
*
* Also clears { link until_date} and { link until_exact_time}.
diff --git a/src/host/host-create-update-recurring.vala b/src/host/host-create-update-recurring.vala
index 20b2a6a..7c4ba87 100644
--- a/src/host/host-create-update-recurring.vala
+++ b/src/host/host-create-update-recurring.vala
@@ -13,8 +13,8 @@ public class CreateUpdateRecurring : Gtk.Grid, Toolkit.Card {
private const string PROP_START_DATE = "start-date";
private const string PROP_END_DATE = "end-date";
- // DO NOT CHANGE UNLESS YOU KNOW WHAT YOU'RE DOING. These values are mirrored in the Glade
- // file's repeats_combobox model.
+ // DO NOT CHANGE VALUES UNLESS YOU KNOW WHAT YOU'RE DOING. These values are mirrored in the
+ // Glade file's repeats_combobox model.
private enum Repeats {
DAILY = 0,
WEEKLY = 1,
@@ -56,6 +56,27 @@ public class CreateUpdateRecurring : Gtk.Grid, Toolkit.Card {
private Gtk.Box on_days_box;
[GtkChild]
+ private Gtk.CheckButton sunday_checkbutton;
+
+ [GtkChild]
+ private Gtk.CheckButton monday_checkbutton;
+
+ [GtkChild]
+ private Gtk.CheckButton tuesday_checkbutton;
+
+ [GtkChild]
+ private Gtk.CheckButton wednesday_checkbutton;
+
+ [GtkChild]
+ private Gtk.CheckButton thursday_checkbutton;
+
+ [GtkChild]
+ private Gtk.CheckButton friday_checkbutton;
+
+ [GtkChild]
+ private Gtk.CheckButton saturday_checkbutton;
+
+ [GtkChild]
private Gtk.Button start_date_button;
[GtkChild]
@@ -80,6 +101,9 @@ public class CreateUpdateRecurring : Gtk.Grid, Toolkit.Card {
private Gtk.Button ok_button;
private new Component.Event? event = null;
+ private Component.Event? master = null;
+ private Gee.HashMap<Calendar.DayOfWeek, Gtk.CheckButton> on_day_checkbuttons = new Gee.HashMap<
+ Calendar.DayOfWeek, Gtk.CheckButton>();
private bool blocking_insert_text_numbers_only_signal = false;
public CreateUpdateRecurring() {
@@ -104,6 +128,15 @@ public class CreateUpdateRecurring : Gtk.Grid, Toolkit.Card {
transform_date_to_string);
bind_property(PROP_END_DATE, end_date_button, "label", BindingFlags.SYNC_CREATE,
transform_date_to_string);
+
+ // map on-day checkboxes to days of week
+ on_day_checkbuttons[Calendar.DayOfWeek.SUN] = sunday_checkbutton;
+ on_day_checkbuttons[Calendar.DayOfWeek.MON] = monday_checkbutton;
+ on_day_checkbuttons[Calendar.DayOfWeek.TUE] = tuesday_checkbutton;
+ on_day_checkbuttons[Calendar.DayOfWeek.WED] = wednesday_checkbutton;
+ on_day_checkbuttons[Calendar.DayOfWeek.THU] = thursday_checkbutton;
+ on_day_checkbuttons[Calendar.DayOfWeek.FRI] = friday_checkbutton;
+ on_day_checkbuttons[Calendar.DayOfWeek.SAT] = saturday_checkbutton;
}
private bool transform_repeats_active_to_on_days_visible(Binding binding, Value source_value,
@@ -126,25 +159,124 @@ public class CreateUpdateRecurring : Gtk.Grid, Toolkit.Card {
// *must* have an Event by this point, whether from before or due to this jump
assert(event != null);
+
+ // need to load the master component in order to update the RRULE (which isn't stored in
+ // the generated instances)
+ load_master_async.begin();
+ }
+
+ private async void load_master_async() {
+ try {
+ Component.Instance master_instance = yield event.calendar_source.fetch_master_component_async(
+ event.uid, null);
+ master = master_instance as Component.Event;
+ } catch (Error err) {
+ debug("Unable to load master from %s: %s", event.calendar_source.to_string(),
+ err.message);
+
+ master = null;
+ }
+
+ if (master == null) {
+ jump_back();
+
+ return;
+ }
+
update_controls();
}
private void update_controls() {
- make_recurring_checkbutton.active = (event.rrule != null);
+ assert(master != null);
- // set to defaults if not a recurring event
- if (event.rrule == null) {
+ make_recurring_checkbutton.active = (master.rrule != null);
+
+ // some defaults that may not be set even if an RRULE is present
+
+ // "Ends ... After" entry
+ after_entry.text = "1";
+
+ // "Starts" and "Ends...On" entries
+ Calendar.DateSpan event_span = master.get_event_date_span(Calendar.Timezone.local);
+ start_date = event_span.start_date;
+ end_date = event_span.end_date;
+
+ // Clear all "On days" checkboxes for sanity's sake
+ foreach (Gtk.CheckButton checkbutton in on_day_checkbuttons.values)
+ checkbutton.active = false;
+
+ // set remaining defaults if not a recurring event
+ if (master.rrule == null) {
repeats_combobox.active = Repeats.DAILY;
every_entry.text = "1";
never_radiobutton.active = true;
- after_entry.text = "1";
-
- Calendar.DateSpan event_span = event.get_event_date_span(Calendar.Timezone.local);
- start_date = event_span.start_date;
- end_date = event_span.end_date;
return;
}
+
+ // "Repeats" combobox
+ switch (master.rrule.freq) {
+ case iCal.icalrecurrencetype_frequency.DAILY_RECURRENCE:
+ repeats_combobox.active = Repeats.DAILY;
+ break;
+
+ case iCal.icalrecurrencetype_frequency.WEEKLY_RECURRENCE:
+ repeats_combobox.active = Repeats.WEEKLY;
+ break;
+
+ // TODO: Don't support MONTHLY RRULEs with multiple ByRules or ByRules we can't
+ // represent ... basically, non-simple repeating rules
+ case iCal.icalrecurrencetype_frequency.MONTHLY_RECURRENCE:
+ bool by_day = master.rrule.get_by_rule(Component.RecurrenceRule.ByRule.DAY).size > 0;
+ bool by_monthday = master.rrule.get_by_rule(Component.RecurrenceRule.ByRule.MONTH_DAY).size
0;
+
+ if (by_day && !by_monthday)
+ repeats_combobox.active = Repeats.DAY_OF_THE_WEEK;
+ else if (!by_day && by_monthday)
+ repeats_combobox.active = Repeats.DAY_OF_THE_MONTH;
+ else
+ assert_not_reached();
+ break;
+
+ case iCal.icalrecurrencetype_frequency.YEARLY_RECURRENCE:
+ repeats_combobox.active = Repeats.YEARLY;
+ break;
+
+ // TODO: Don't support sub-day RRULEs
+ default:
+ assert_not_reached();
+ }
+
+ // "Every" entry
+ every_entry.text = master.rrule.interval.to_string();
+
+ // "On days" week day checkboxes are only visible if a WEEKLY event
+ if (master.rrule.is_weekly) {
+ Gee.Map<Calendar.DayOfWeek?, int> by_days =
+
Component.RecurrenceRule.decode_days(master.rrule.get_by_rule(Component.RecurrenceRule.ByRule.DAY));
+
+ // the presence of a "null" day means every or all days
+ if (by_days.has_key(null)) {
+ foreach (Gtk.CheckButton checkbutton in on_day_checkbuttons.values)
+ checkbutton.active = true;
+ } else {
+ foreach (Calendar.DayOfWeek dow in by_days.keys)
+ on_day_checkbuttons[dow].active = true;
+ }
+ }
+
+ // "Ends" choices
+ if (!master.rrule.has_duration) {
+ never_radiobutton.active = true;
+ } else if (master.rrule.count > 0) {
+ after_radiobutton.active = true;
+ after_entry.text = master.rrule.count.to_string();
+ } else {
+ assert(master.rrule.until_date != null || master.rrule.until_exact_time != null);
+
+ ends_on_radiobutton.active = true;
+ end_date = master.rrule.get_recurrence_end_date();
+ }
}
[GtkCallback]
@@ -228,7 +360,8 @@ public class CreateUpdateRecurring : Gtk.Grid, Toolkit.Card {
.to_string(ch => ch.to_string());
// insert new text into place, ensure this handler doesn't attempt to process this
- // modified text
+ // modified text ... would use SignalHandler.block_by_func() and unblock_by_func(), but
+ // the bindings are ungood
if (!String.is_empty(numbers_only)) {
blocking_insert_text_numbers_only_signal = true;
editable.insert_text(numbers_only, numbers_only.length, ref position);
diff --git a/src/host/host-main-window.vala b/src/host/host-main-window.vala
index 72327bb..e2ebb2f 100644
--- a/src/host/host-main-window.vala
+++ b/src/host/host-main-window.vala
@@ -424,7 +424,7 @@ public class MainWindow : Gtk.ApplicationWindow {
}
private void quick_create_event(Component.Event? initial, Gtk.Widget relative_to, Gdk.Point?
for_location) {
- QuickCreateEvent quick_create = new QuickCreateEvent(initial);
+ QuickCreateEvent quick_create = new QuickCreateEvent();
CreateUpdateEvent create_update = new CreateUpdateEvent();
create_update.is_update = false;
@@ -437,6 +437,9 @@ public class MainWindow : Gtk.ApplicationWindow {
.to_array_list()
);
+ // initialize the Deck with the initial event (if any)
+ deck.go_home(initial);
+
show_deck(relative_to, for_location, deck);
}
diff --git a/src/host/host-quick-create-event.vala b/src/host/host-quick-create-event.vala
index e4ca931..869e7f2 100644
--- a/src/host/host-quick-create-event.vala
+++ b/src/host/host-quick-create-event.vala
@@ -40,15 +40,18 @@ public class QuickCreateEvent : Gtk.Grid, Toolkit.Card {
private Toolkit.ComboBoxTextModel<Backing.CalendarSource> model;
- public QuickCreateEvent(Component.Event? initial) {
- event = initial;
+ public QuickCreateEvent() {
+ }
+
+ public void jumped_to(Toolkit.Card? from, Toolkit.Card.Jump reason, Value? message) {
+ event = message as Component.Event;
// if initial date/times supplied, reveal to the user and change the example
string eg;
- if (initial != null && (initial.date_span != null || initial.exact_time_span != null)) {
+ if (event != null && (event.date_span != null || event.exact_time_span != null)) {
when_box.visible = true;
- when_text_label.label = initial.get_event_time_pretty_string(Calendar.Timezone.local);
- if (initial.date_span != null)
+ when_text_label.label = event.get_event_time_pretty_string(Calendar.Timezone.local);
+ if (event.date_span != null)
eg = _("Example: Dinner at Tadich Grill 7:30pm");
else
eg = _("Example: Dinner at Tadich Grill");
@@ -76,9 +79,6 @@ public class QuickCreateEvent : Gtk.Grid, Toolkit.Card {
calendar_combo_box.active = 0;
}
- public void jumped_to(Toolkit.Card? from, Toolkit.Card.Jump reason, Value? message) {
- }
-
[GtkCallback]
private void on_details_entry_icon_release(Gtk.Entry entry, Gtk.EntryIconPosition icon,
Gdk.Event event) {
diff --git a/src/host/host-show-event.vala b/src/host/host-show-event.vala
index af4da0e..c647be4 100644
--- a/src/host/host-show-event.vala
+++ b/src/host/host-show-event.vala
@@ -90,7 +90,7 @@ public class ShowEvent : Gtk.Grid, Toolkit.Card {
// https://bugzilla.gnome.org/show_bug.cgi?id=725786
bool read_only = event.calendar_source != null && event.calendar_source.read_only;
- bool updatable = !event.is_recurring && !read_only;
+ bool updatable = !event.is_recurring_instance && !read_only;
update_button.visible = updatable;
update_button.no_show_all = updatable;
@@ -142,7 +142,7 @@ public class ShowEvent : Gtk.Grid, Toolkit.Card {
//
// TODO: Gtk.Stack would be a better widget for this animation, but it's unavailable in
// Glade as of GTK+ 3.12.
- if (event.is_recurring) {
+ if (event.is_recurring_instance) {
button_box_revealer.reveal_child = false;
remove_recurring_revealer.reveal_child = true;
diff --git a/src/rc/create-update-recurring.ui b/src/rc/create-update-recurring.ui
index eda59b6..2a6456f 100644
--- a/src/rc/create-update-recurring.ui
+++ b/src/rc/create-update-recurring.ui
@@ -16,6 +16,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
+ <property name="halign">start</property>
<property name="valign">start</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
@@ -33,8 +34,8 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">16</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">6</property>
+ <property name="row_spacing">8</property>
+ <property name="column_spacing">8</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
@@ -343,7 +344,7 @@
<property name="spacing">4</property>
<child>
<object class="GtkRadioButton" id="after_radiobutton">
- <property name="label" translatable="yes">Aft_er</property>
+ <property name="label" translatable="yes" comments="As in, "After n
events"">Aft_er</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@@ -380,7 +381,7 @@
<object class="GtkLabel" id="after_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label" translatable="yes">events</property>
+ <property name="label">(none)</property>
</object>
<packing>
<property name="expand">False</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]