Calendar: Show multi-day event continuation
Currently, multi-day events are shown as individual appointments on each day. This patch ellipsizes multi-day events to indicate continuation on the prior or following day (or other time-period.) The time label spot is now replaced by a box layout that contains the prefix ellipsis label, the time label and the postfix ellipsis label. In order to keep the alignment, ellipses are merely invisible (zero opacity) when hidden. The ellipses are styled using the events-day-time-ellipses class which, by default, take the color of the event text. When RTL is used, the box contents are adjusted accordingly (clutter does that for us). An event spanning three days now displays "...All Day..." in the calendar on the second day. https://bugzilla.gnome.org/show_bug.cgi?id=727302
This commit is contained in:
parent
34606c0a8c
commit
65c136f4ed
@ -1494,6 +1494,10 @@ StScrollBar StButton#vhandle:active {
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.events-day-time-ellipses {
|
||||||
|
color: rgba(153, 153, 153, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
.events-day-time:rtl {
|
.events-day-time:rtl {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,13 @@ const Shell = imports.gi.Shell;
|
|||||||
|
|
||||||
const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||||
const SHOW_WEEKDATE_KEY = 'show-weekdate';
|
const SHOW_WEEKDATE_KEY = 'show-weekdate';
|
||||||
|
const ELLIPSIS_CHAR = '\u2026';
|
||||||
|
const EventEllipses = {
|
||||||
|
NONE: 0,
|
||||||
|
BEFORE: 1 << 0,
|
||||||
|
AFTER: 1 << 1,
|
||||||
|
BOTH: ~0
|
||||||
|
};
|
||||||
|
|
||||||
// alias to prevent xgettext from picking up strings translated in GTK+
|
// alias to prevent xgettext from picking up strings translated in GTK+
|
||||||
const gtk30_ = Gettext_gtk30.gettext;
|
const gtk30_ = Gettext_gtk30.gettext;
|
||||||
@ -59,19 +66,33 @@ function _getEndOfDay(date) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _formatEventTime(event, clockFormat) {
|
function _ellipsizeEventTime(event, periodBegin, periodEnd) {
|
||||||
|
if (event.allDay)
|
||||||
|
return EventEllipses.NONE;
|
||||||
|
|
||||||
|
let ret = EventEllipses.NONE;
|
||||||
|
if (event.date < periodBegin)
|
||||||
|
ret = EventEllipses.BEFORE;
|
||||||
|
if (event.end > periodEnd)
|
||||||
|
ret |= EventEllipses.AFTER;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _formatEventTime(event, clockFormat, periodBegin, periodEnd) {
|
||||||
let ret;
|
let ret;
|
||||||
if (event.allDay) {
|
let allDay = (event.allDay || (event.date <= periodBegin && event.end >= periodEnd));
|
||||||
|
if (allDay) {
|
||||||
/* Translators: Shown in calendar event list for all day events
|
/* Translators: Shown in calendar event list for all day events
|
||||||
* Keep it short, best if you can use less then 10 characters
|
* Keep it short, best if you can use less then 10 characters
|
||||||
*/
|
*/
|
||||||
ret = C_("event list time", "All Day");
|
ret = C_("event list time", "All Day");
|
||||||
} else {
|
} else {
|
||||||
|
let date = event.date >= periodBegin ? event.date : event.end;
|
||||||
switch (clockFormat) {
|
switch (clockFormat) {
|
||||||
case '24h':
|
case '24h':
|
||||||
/* Translators: Shown in calendar event list, if 24h format,
|
/* Translators: Shown in calendar event list, if 24h format,
|
||||||
\u2236 is a ratio character, similar to : */
|
\u2236 is a ratio character, similar to : */
|
||||||
ret = event.date.toLocaleFormat(C_("event list time", "%H\u2236%M"));
|
ret = date.toLocaleFormat(C_("event list time", "%H\u2236%M"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -80,7 +101,7 @@ function _formatEventTime(event, clockFormat) {
|
|||||||
/* Translators: Shown in calendar event list, if 12h format,
|
/* Translators: Shown in calendar event list, if 12h format,
|
||||||
\u2236 is a ratio character, similar to : and \u2009 is
|
\u2236 is a ratio character, similar to : and \u2009 is
|
||||||
a thin space */
|
a thin space */
|
||||||
ret = event.date.toLocaleFormat(C_("event list time", "%l\u2236%M\u2009%p"));
|
ret = date.toLocaleFormat(C_("event list time", "%l\u2236%M\u2009%p"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -722,12 +743,16 @@ const EventsList = new Lang.Class({
|
|||||||
this._eventSource.connect('changed', Lang.bind(this, this._update));
|
this._eventSource.connect('changed', Lang.bind(this, this._update));
|
||||||
},
|
},
|
||||||
|
|
||||||
_addEvent: function(event, index, includeDayName) {
|
_addEvent: function(event, index, includeDayName, periodBegin, periodEnd) {
|
||||||
let dayString;
|
let dayString;
|
||||||
if (includeDayName)
|
if (includeDayName) {
|
||||||
|
if (event.date >= periodBegin)
|
||||||
dayString = _getEventDayAbbreviation(event.date.getDay());
|
dayString = _getEventDayAbbreviation(event.date.getDay());
|
||||||
else
|
else /* show event end day if it began earlier */
|
||||||
|
dayString = _getEventDayAbbreviation(event.end.getDay());
|
||||||
|
} else {
|
||||||
dayString = '';
|
dayString = '';
|
||||||
|
}
|
||||||
|
|
||||||
let dayLabel = new St.Label({ style_class: 'events-day-dayname',
|
let dayLabel = new St.Label({ style_class: 'events-day-dayname',
|
||||||
text: dayString,
|
text: dayString,
|
||||||
@ -740,16 +765,31 @@ const EventsList = new Lang.Class({
|
|||||||
|
|
||||||
let layout = this.actor.layout_manager;
|
let layout = this.actor.layout_manager;
|
||||||
layout.attach(dayLabel, rtl ? 2 : 0, index, 1, 1);
|
layout.attach(dayLabel, rtl ? 2 : 0, index, 1, 1);
|
||||||
|
|
||||||
let clockFormat = this._desktopSettings.get_string(CLOCK_FORMAT_KEY);
|
let clockFormat = this._desktopSettings.get_string(CLOCK_FORMAT_KEY);
|
||||||
let timeString = _formatEventTime(event, clockFormat);
|
let timeString = _formatEventTime(event, clockFormat, periodBegin, periodEnd);
|
||||||
let timeLabel = new St.Label({ style_class: 'events-day-time',
|
let timeLabel = new St.Label({ style_class: 'events-day-time',
|
||||||
text: timeString,
|
text: timeString,
|
||||||
y_align: Clutter.ActorAlign.START });
|
y_align: Clutter.ActorAlign.START });
|
||||||
timeLabel.clutter_text.line_wrap = false;
|
timeLabel.clutter_text.line_wrap = false;
|
||||||
timeLabel.clutter_text.ellipsize = false;
|
timeLabel.clutter_text.ellipsize = false;
|
||||||
|
|
||||||
layout.attach(timeLabel, 1, index, 1, 1);
|
let ellipses = _ellipsizeEventTime(event, periodBegin, periodEnd);
|
||||||
|
let preEllipsisLabel = new St.Label({ style_class: 'events-day-time-ellipses',
|
||||||
|
text: ELLIPSIS_CHAR,
|
||||||
|
y_align: Clutter.ActorAlign.START });
|
||||||
|
let postEllipsisLabel = new St.Label({ style_class: 'events-day-time-ellipses',
|
||||||
|
text: ELLIPSIS_CHAR,
|
||||||
|
y_align: Clutter.ActorAlign.START });
|
||||||
|
if (!(ellipses & EventEllipses.BEFORE))
|
||||||
|
preEllipsisLabel.opacity = 0;
|
||||||
|
if (!(ellipses & EventEllipses.AFTER))
|
||||||
|
postEllipsisLabel.opacity = 0;
|
||||||
|
|
||||||
|
let timeLabelBoxLayout = new St.BoxLayout();
|
||||||
|
timeLabelBoxLayout.add(preEllipsisLabel);
|
||||||
|
timeLabelBoxLayout.add(timeLabel);
|
||||||
|
timeLabelBoxLayout.add(postEllipsisLabel);
|
||||||
|
layout.attach(timeLabelBoxLayout, 1, index, 1, 1);
|
||||||
|
|
||||||
let titleLabel = new St.Label({ style_class: 'events-day-task',
|
let titleLabel = new St.Label({ style_class: 'events-day-task',
|
||||||
text: event.summary,
|
text: event.summary,
|
||||||
@ -760,8 +800,8 @@ const EventsList = new Lang.Class({
|
|||||||
layout.attach(titleLabel, rtl ? 0 : 2, index, 1, 1);
|
layout.attach(titleLabel, rtl ? 0 : 2, index, 1, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
_addPeriod: function(header, index, begin, end, includeDayName, showNothingScheduled) {
|
_addPeriod: function(header, index, periodBegin, periodEnd, includeDayName, showNothingScheduled) {
|
||||||
let events = this._eventSource.getEvents(begin, end);
|
let events = this._eventSource.getEvents(periodBegin, periodEnd);
|
||||||
|
|
||||||
if (events.length == 0 && !showNothingScheduled)
|
if (events.length == 0 && !showNothingScheduled)
|
||||||
return index;
|
return index;
|
||||||
@ -772,15 +812,14 @@ const EventsList = new Lang.Class({
|
|||||||
index++;
|
index++;
|
||||||
|
|
||||||
for (let n = 0; n < events.length; n++) {
|
for (let n = 0; n < events.length; n++) {
|
||||||
this._addEvent(events[n], index, includeDayName);
|
this._addEvent(events[n], index, includeDayName, periodBegin, periodEnd);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events.length == 0 && showNothingScheduled) {
|
if (events.length == 0 && showNothingScheduled) {
|
||||||
let now = new Date();
|
|
||||||
/* Translators: Text to show if there are no events */
|
/* Translators: Text to show if there are no events */
|
||||||
let nothingEvent = new CalendarEvent(now, now, _("Nothing Scheduled"), true);
|
let nothingEvent = new CalendarEvent(periodBegin, periodBegin, _("Nothing Scheduled"), true);
|
||||||
this._addEvent(nothingEvent, index, false);
|
this._addEvent(nothingEvent, index, false, periodBegin, periodEnd);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user