...
 
Commits (145)
Evolution 3.20.5 2016-08-08
---------------------------
Bug Fixes:
Bug 768449 - “Message/Open in New Window” marks message as read when shouldn't (Milan Crha)
Bug 767283 - [Wayland] "Add a Column" dialog: drag and drop broken ][ (Milan Crha)
Bug 769338 - Pasting < > & as a quotation pastes their html entities (Tomas Popela)
Bug 769354 - Quotation level changed when deleting one character in quoted line (Tomas Popela)
Bug 769062 - Crash on mouse over task when tasks are grouped (Milan Crha)
Bug 768683 - Cannot mark as spam non-spam message in a real Junk folder (Milan Crha)
Bug 769072 - Silently discards message when save to draft fails on quit (Milan Crha)
Bug 769523 - bold key/button erases text (Tomas Popela)
Bug 769288 - Crash after saving view and changing folder (Milan Crha)
Miscellaneous:
EComposerPrivate - Changing a top signature to another one will place it on different position (Tomas Popela)
EComposerPrivate - Unneeded spacer left when setting a top signature from an existing one to None (Tomas Popela)
EHTMLEditorView - Redoing unquoting does not work (Tomas Popela)
Correct order of "assign value" and "call function" when saving to drafts (Milan Crha)
Evolution 3.20.4 2016-07-11
---------------------------
Bug Fixes:
Bug 767283 - "Add a Column" dialog: drag and drop broken on Wayland (Milan Crha)
Bug 767236 - quick correction spell check in context menu is gone (Tomas Popela)
Bug 767334 - Unable to open attachments when I am not the organiser (Milan Crha)
Bug 767542 - Correct encrypted-only message formatter color and icon (Milan Crha)
Bug 767364 - Tooltips over task/memo list are misplaced (Milan Crha)
Bug 767335 - Attachment names are not URL-decoded (Milan Crha)
Bug 767780 - The "References" header folded twice (Milan Crha)
Bug 767681 - regression: Evolution 3.20.3-1 inserts blank line at the start of the signature (Tomas Popela)
Bug 768013 - [Wayland] Drag and drop copies emails instead of moving them (Milan Crha)
Bug 768369 - Avoid "Quit with unsent messages" question without shell window (Milan Crha)
Miscellaneous:
Crash under e_mail_folder_find_duplicate_messages_sync() (Milan Crha)
Create new events in the selected calendar in the left tree of calendars (Milan Crha)
When pressing the Return key to end a list a new empty list is created (Tomas Popela)
Don't create unnecessary wrappers when quoting a text (Tomas Popela)
Busy-loop when printing specifically formatted HTML message (Milan Crha)
GalA11yETableItem can have stored incorrect row count sometimes (Milan Crha)
EHTMLEditorActions - Disable HTML actions in plain text mode (Tomas Popela)
EHTMLEditorSelection - List alignment not detected properly (Tomas Popela)
EHTMLEditorSelection - Indented block style could not be set properly (Tomas Popela)
EHTMLEditorSelection - Use a faster way of quoting an element in the plain text mode (Tomas Popela)
EHTMLEditorView - Opening a draft that was not created in composer should respect the wrap/don't wrap preference (Tomas Popela)
EHTMLEditorView - Critical warning could be seen in console after pasting the content (Tomas Popela)
EHTMLEditorView - Don't leak a WebKitDOMNodeList instance (Tomas Popela)
EHTMLEditorView - Pasting content into the indented block will not preserve formatting (Tomas Popela)
EHTMLEditorView - Don't add a new line for the empty list when generating a plain text version of the content (Tomas Popela)
EHTMLEditorView - Don't leak a WebKitODMNodeList instance (Tomas Popela)
EHTMLEditorView - Always try to process the CID images when loading a content (Tomas Popela)
EHTMLEditorView - Correct the situations when the 'Lose formatting' dialog is showed (Tomas Popela)
EHTMLEditorView - When the content is converted set the editor as changed (Tomas Popela)
EHTMLEditorView - Plain text version of draft could lose formatting (Tomas Popela)
EHTMLEditorView - Improve how the content is processed to plain text (Tomas Popela)
EHTMLEditorView - Correctly remove images and its wrappers (Tomas Popela)
EHTMLEditorView - Indented elements should be preserved when switching between composer modes (Tomas Popela)
EHTMLEditorView - Fix the build after doing a mistake in commits (Tomas Popela)
EHTMLEditorView - Redoing a delete operation in a PRE element could wrap the content in SPAN element (Tomas Popela)
EHTMLEditorView - Some empty new lines in a quoted content could be lost (Tomas Popela)
EHTMLEditorView - Don't modify a variable from arguments (Tomas Popela)
EHTMLEditorView - Simplify how an element is quoted (Tomas Popela)
Translations:
Anders Jonsson (sv)
Evolution 3.20.3 2016-06-06
---------------------------
Bug Fixes:
Bug 766540 - Add missing library to build of calendar/gui/ (Tim Lunn)
Bug 766713 - Remove attachment does not work on multiple level message structure (Milan Crha)
Miscellaneous:
Fix some issues found by Coverity Scan, cppcheck and clang (Milan Crha)
Explicitly center attachment bar expander vertically (Milan Crha)
Avoid NULL dereference in mail-send-recv.c:free_send_data() function (Milan Crha)
EHTMLEditorActions - Paste Quotation action is always active (Tomas Popela)
EHTMLEditorImageDialog - Border and alignment are not set properly (Tomas Popela)
EHTMLEditorView - Background image from page is removed when saving draft (Tomas Popela)
Translations:
Sveinn í Felli (is)
Kjartan Maraas (nb)
Evolution 3.20.2 2016-05-09
---------------------------
Bug Fixes:
Bug 765090 - Replying to a message with a reply to an inline patch loses parts at the end of the patch. (Tomas Popela)
Bug 765102 - [Wayland] Tooltips for calendar events are misplaced (Milan Crha)
Bug 765202 - Reply to List for MIME digest sub-messages (Milan Crha)
Bug 765446 - Mail: View->Current view->... no updated on folder change (Milan Crha)
Bug 765665 - Notification doesn't use user selected date/time format (Milan Crha)
Bug 765636 - Runtime warning from spi_register_deregister_object() on quit (Milan Crha)
Bug 435219 - Treat Sent/Outbox subfolders as outgoing folders too (Milan Crha)
Bug 765950 - Search bar text change should enable Next/Prev buttons (Milan Crha)
Bug 766017 - Taskpad/Memopad Calendar popup menus not updated on popup (Milan Crha)
Miscellaneous:
Optimize some of the DOM functions related to selection (Tomas Popela)
EMsgComposer - Move the DOM manipulation to EHTMLEditorView (Tomas Popela)
EHTMLEditorActions - 'Select All' action is always disabled (Tomas Popela)
EHTMLEditorView - Deleting a content in a PRE element could wrap the content in SPAN element (Tomas Popela)
EHTMLEditorView - Moving a Preformatted block one level up in the quoted content will change it to Normal (Tomas Popela)
EHTMLEditorView - Restore the selection end mark correctly when processing HTML to plain text (Tomas Popela)
EHTMLEditorView - Redoing a citation split removes an extra text (Tomas Popela)
EHTMLEditorView - Simplify and improve how the undo/redo of delete operation in quoted content is performed (Tomas Popela)
Recognize special folders for a global mail view also based on flags (Milan Crha)
Rather hide, than disable, items in Taskpad/Memopad context menus (Milan Crha)
Correct placement of emoticon and color chooser in composer under Wayland (Milan Crha)
Translations:
Kjartan Maraas (nb)
Evolution 3.20.1 2016-04-11
---------------------------
Bug Fixes:
Bug 736808 - Fill lists of certificates asynchronously (Milan Crha)
Bug 763796 - Excessive runtime warnings from gtk_style_context_get_...() (Milan Crha)
Bug 764062 - Send/Receive dialog can be left opened with empty content (Milan Crha)
Bug 764234 - Add more handling options for Content-Type: message/rfc822 (Milan Crha)
Bug 764172 - Do not grab mouse on left-click in message list (Milan Crha)
Bug 763723 - Do not propagate mouse events to parent of EAttachmentBar (Milan Crha)
Bug 764426 - Contact list with umlauts shown encoded in meetings (Milan Crha)
Bug 764428 - Empty state text in Contacts view is not properly centered (Milan Crha)
Bug 240130 - Resize table header on theme font change (Milan Crha)
Bug 764542 - ECalendar next/previous month arrows oversized in gtk+ 3.20 (Milan Crha)
Bug 762785 - Avoid unnecessary MessageList rebuilds (Milan Crha)
Bug 758878 - Asked repeatedly for a Google account password (with calendar) (Milan Crha)
Miscellaneous:
[EAttachmentTree/IconView] Setup widgets in 'constructed' handler (Milan Crha)
Remove unneeded runtime warning from e-day-view.c::cancel_editing() (Milan Crha)
Vertically center table header text (Milan Crha)
Make some settings changes in mail composer permanent (Milan Crha)
Add missing closing double quote, thus webview-print.css is actually used (Milan Crha)
Reposition ECalendar children on timeout, not inside size-allocate handler (Milan Crha)
Cannot change order list to unordered for the first time (Tomas Popela)
Inline images in drafts are not displayed in GMail (Tomas Popela)
EHTMLEditorView - Remove signature from Thunderbird if presented (Tomas Popela)
EHTMLEditorView - Correct the new lines handling in quoted content (Tomas Popela)
EHTMLEditorView - Avoid variables with the same name in one scope (Tomas Popela)
EHTMLEditorView - Don't replace various whitespaces with non-breaking spaces when inserting into PRE element (Tomas Popela)
EHTMLEditorView - Busy loop after pasting two links after each other in the quoted content (Tomas Popela)
EHTMLEditorSelection - Selection could be saved wrong in quoted content (Tomas Popela)
EHTMLEditorSelection - Anchors could be wrongly wrapped in quoted content (Tomas Popela)
EHTMLEditorSelection - Ask for a parent node of the right node (Tomas Popela)
Translations:
Dušan Kazik (sk)
Daniel Korostil (uk)
Tiago Carrondo (pt)
Inaki Larranaga Murgoitio (eu)
Cédric Valmary (oc)
Gianvito Cavasoli (it)
Mingye Wang (zh_CN)
Evolution 3.20.0 2016-03-21
---------------------------
......
......@@ -163,14 +163,9 @@ ea_minicard_get_name (AtkObject *accessible)
g_string_append (new_str, string);
g_free (string);
/* if there exist no enough space for remain info, return */
if (new_str->len >= BUFFERSIZE) {
strncpy (name, new_str->str, BUFFERSIZE);
name[BUFFERSIZE] = '\0';
return name;
}
strncpy (name, new_str->str, new_str->len + 1 >= BUFFERSIZE ? BUFFERSIZE : new_str->len + 1);
name[BUFFERSIZE] = '\0';
strcpy (name, new_str->str);
g_string_free (new_str, TRUE);
ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name);
......
......@@ -806,8 +806,10 @@ get_address_format (AddressFormat address_format,
g_key_file_load_from_file (key_file, EVOLUTION_RULEDIR "/address_formats.dat", 0, &error);
if (error != NULL) {
g_warning ("%s: Failed to load address_formats.dat file: %s", G_STRFUNC, error->message);
*format = g_strdup (ADDRESS_DEFAULT_FORMAT);
*country_position = g_strdup (ADDRESS_DEFAULT_COUNTRY_POSITION);
if (format)
*format = g_strdup (ADDRESS_DEFAULT_FORMAT);
if (country_position)
*country_position = g_strdup (ADDRESS_DEFAULT_COUNTRY_POSITION);
g_key_file_free (key_file);
g_free (loc);
g_error_free (error);
......
......@@ -436,7 +436,7 @@ notified_alarms_dialog_new (void)
* @trigger: Trigger time for the alarm.
* @occur_start: Start of occurrence time for the event.
* @occur_end: End of occurrence time for the event.
* @vtype: Type of the component which corresponds to the alarm.
* @comp: The #ECalComponent which corresponds to the alarm.
* @summary: Short summary of the appointment
* @description: Long description of the appointment
* @location: Location of the appointment
......@@ -454,7 +454,7 @@ add_alarm_to_notified_alarms_dialog (AlarmNotificationsDialog *na,
time_t trigger,
time_t occur_start,
time_t occur_end,
ECalComponentVType vtype,
ECalComponent *comp,
const gchar *summary,
const gchar *description,
const gchar *location,
......@@ -464,11 +464,15 @@ add_alarm_to_notified_alarms_dialog (AlarmNotificationsDialog *na,
GtkTreeIter iter = { 0 };
GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (na->treeview));
AlarmFuncInfo *funcinfo = NULL;
gchar *to_display = NULL, *start, *end, *str_time;
ECalComponentVType vtype;
gchar *to_display = NULL, *start, *str_time;
icaltimezone *current_zone;
/* Iter is not yet defined but still we return it in all the g_return_val_if_fail() calls? */
g_return_val_if_fail (trigger != -1, iter);
g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), iter);
vtype = e_cal_component_get_vtype (comp);
/* Only VEVENTs or VTODOs can have alarms */
g_return_val_if_fail (vtype == E_CAL_COMPONENT_EVENT || vtype == E_CAL_COMPONENT_TODO, iter);
......@@ -484,14 +488,12 @@ add_alarm_to_notified_alarms_dialog (AlarmNotificationsDialog *na,
gtk_list_store_append (GTK_LIST_STORE (model), &iter);
current_zone = config_data_get_timezone ();
start = timet_to_str_with_zone (occur_start, current_zone);
end = timet_to_str_with_zone (occur_end, current_zone);
start = timet_to_str_with_zone (occur_start, current_zone, datetime_is_date_only (comp, DATETIME_CHECK_DTSTART));
str_time = calculate_time (occur_start, occur_end);
to_display = g_markup_printf_escaped (
"<big><b>%s</b></big>\n%s %s",
summary, start, str_time);
g_free (start);
g_free (end);
gtk_list_store_set (
GTK_LIST_STORE (model), &iter,
ALARM_DISPLAY_COLUMN, to_display, -1);
......
......@@ -52,7 +52,7 @@ GtkTreeIter add_alarm_to_notified_alarms_dialog
time_t trigger,
time_t occur_start,
time_t occur_end,
ECalComponentVType vtype,
ECalComponent *comp,
const gchar *summary,
const gchar *description,
const gchar *location,
......
......@@ -731,7 +731,8 @@ remove_alarms (CompQueuedAlarms *cqa,
l = l->next;
alarm_remove (qa->alarm_id);
remove_queued_alarm (cqa, qa->alarm_id, free_object, FALSE);
if (remove_queued_alarm (cqa, qa->alarm_id, free_object, FALSE))
break;
}
}
......@@ -1508,7 +1509,7 @@ open_alarm_dialog (TrayIconData *tray_data)
tray_data->trigger,
qa->instance->occur_start,
qa->instance->occur_end,
e_cal_component_get_vtype (tray_data->comp),
tray_data->comp,
tray_data->summary,
tray_data->description,
tray_data->location,
......@@ -1693,7 +1694,7 @@ display_notification (time_t trigger,
TrayIconData *tray_data;
ECalComponentText text;
GSList *text_list;
gchar *str, *start_str, *end_str, *alarm_str, *time_str;
gchar *str, *start_str, *alarm_str, *time_str;
icaltimezone *current_zone;
ECalComponentOrganizer organiser;
......@@ -1747,9 +1748,8 @@ display_notification (time_t trigger,
}
current_zone = config_data_get_timezone ();
alarm_str = timet_to_str_with_zone (trigger, current_zone);
start_str = timet_to_str_with_zone (qa->instance->occur_start, current_zone);
end_str = timet_to_str_with_zone (qa->instance->occur_end, current_zone);
alarm_str = timet_to_str_with_zone (trigger, current_zone, FALSE);
start_str = timet_to_str_with_zone (qa->instance->occur_start, current_zone, datetime_is_date_only (comp, DATETIME_CHECK_DTSTART));
time_str = calculate_time (qa->instance->occur_start, qa->instance->occur_end);
str = g_strdup_printf (
......@@ -1790,7 +1790,6 @@ display_notification (time_t trigger,
g_free (alarm_summary);
g_free (start_str);
g_free (end_str);
g_free (alarm_str);
g_free (time_str);
g_free (str);
......@@ -1871,7 +1870,7 @@ popup_notification (time_t trigger,
ECalComponent *comp;
const gchar *summary, *location;
gchar *alarm_summary;
gchar *str, *start_str, *end_str, *alarm_str, *time_str;
gchar *str, *start_str, *alarm_str, *time_str;
icaltimezone *current_zone;
ECalComponentOrganizer organiser;
gchar *body;
......@@ -1900,9 +1899,8 @@ popup_notification (time_t trigger,
/* create the tray icon */
current_zone = config_data_get_timezone ();
alarm_str = timet_to_str_with_zone (trigger, current_zone);
start_str = timet_to_str_with_zone (qa->instance->occur_start, current_zone);
end_str = timet_to_str_with_zone (qa->instance->occur_end, current_zone);
alarm_str = timet_to_str_with_zone (trigger, current_zone, FALSE);
start_str = timet_to_str_with_zone (qa->instance->occur_start, current_zone, datetime_is_date_only (comp, DATETIME_CHECK_DTSTART));
time_str = calculate_time (qa->instance->occur_start, qa->instance->occur_end);
str = g_strdup_printf (
......@@ -1956,7 +1954,6 @@ popup_notification (time_t trigger,
g_clear_error (&error);
g_free (alarm_summary);
g_free (start_str);
g_free (end_str);
g_free (alarm_str);
g_free (time_str);
g_free (str);
......
......@@ -26,18 +26,42 @@
#endif
#include <glib/gi18n.h>
#include "e-util/e-util.h"
#include "config-data.h"
#include "util.h"
gboolean
datetime_is_date_only (ECalComponent *comp,
gboolean datetime_check)
{
ECalComponentDateTime dt;
gboolean is_date_only;
g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
dt.value = NULL;
if (datetime_check == DATETIME_CHECK_DTSTART)
e_cal_component_get_dtstart (comp, &dt);
else
e_cal_component_get_dtend (comp, &dt);
is_date_only = dt.value && dt.value->is_date;
e_cal_component_free_datetime (&dt);
return is_date_only;
}
/* Converts a time_t to a string, relative to the specified timezone */
gchar *
timet_to_str_with_zone (time_t t,
icaltimezone *zone)
icaltimezone *zone,
gboolean date_only)
{
struct icaltimetype itt;
struct tm tm;
gchar buf[256];
if (t == -1)
return g_strdup (_("invalid time"));
......@@ -45,9 +69,7 @@ timet_to_str_with_zone (time_t t,
itt = icaltime_from_timet_with_zone (t, FALSE, zone);
tm = icaltimetype_to_tm (&itt);
e_time_format_date_and_time (&tm, config_data_get_24_hour_format (),
FALSE, FALSE, buf, sizeof (buf));
return g_strdup (buf);
return e_datetime_format_format_tm ("calendar", "table", date_only ? DTFormatKindDate : DTFormatKindDateTime, &tm);
}
gchar *
......@@ -57,11 +79,19 @@ calculate_time (time_t start,
time_t difference = end - start;
gchar *str;
gint hours, minutes;
gchar *times[4];
gchar *times[5];
gchar *joined;
gint i;
i = 0;
if (difference >= 24 * 3600) {
gint days;
days = difference / (24 * 3600);
difference %= (24 * 3600);
times[i++] = g_strdup_printf (ngettext ("%d day", "%d days", days), days);
}
if (difference >= 3600) {
hours = difference / 3600;
difference %= 3600;
......
......@@ -27,6 +27,10 @@
#include <libecal/libecal.h>
gchar *timet_to_str_with_zone (time_t t, icaltimezone *zone);
#define DATETIME_CHECK_DTSTART TRUE
#define DATETIME_CHECK_DTEND FALSE
gboolean datetime_is_date_only (ECalComponent *comp, gboolean datetime_check);
gchar *timet_to_str_with_zone (time_t t, icaltimezone *zone, gboolean date_only);
gchar *calculate_time (time_t start, time_t end);
#endif
......@@ -224,6 +224,7 @@ libevolution_calendar_la_LIBADD = \
$(top_builddir)/composer/libevolution-mail-composer.la \
$(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
$(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
$(top_builddir)/addressbook/util/libeabutil.la \
$(top_builddir)/shell/libevolution-shell.la \
$(top_builddir)/calendar/importers/libevolution-calendar-importers.la \
$(top_builddir)/e-util/libevolution-util.la \
......
......@@ -1504,7 +1504,7 @@ new_component_data_free (gpointer ptr)
}
comp_editor = e_comp_editor_open_for_component (NULL, ncd->shell,
ncd->is_new_component ? NULL : e_client_get_source (E_CLIENT (ncd->client)),
ncd->client ? e_client_get_source (E_CLIENT (ncd->client)) : NULL,
e_cal_component_get_icalcomponent (ncd->comp), flags);
if (comp_editor) {
......@@ -1813,7 +1813,7 @@ e_cal_ops_new_component_editor_from_model (ECalModel *model,
if (!for_client_uid)
for_client_uid = e_cal_model_get_default_source_uid (model);
if (for_client_uid && !for_client_uid)
if (for_client_uid && !*for_client_uid)
for_client_uid = NULL;
e_cal_ops_new_component_ex (NULL, model, source_type, for_client_uid, is_assigned, all_day, dtstart, dtend,
......
......@@ -1739,7 +1739,7 @@ tooltip_window_destroyed_cb (gpointer user_data,
gboolean
e_calendar_view_get_tooltips (const ECalendarViewEventData *data)
{
GtkWidget *label, *box, *hbox, *ebox, *frame;
GtkWidget *label, *box, *hbox, *ebox, *frame, *toplevel;
const gchar *str;
gchar *tmp, *tmp1 = NULL, *tmp2 = NULL;
ECalComponentOrganizer organiser;
......@@ -1929,6 +1929,13 @@ e_calendar_view_get_tooltips (const ECalendarViewEventData *data)
}
pevent->tooltip = gtk_window_new (GTK_WINDOW_POPUP);
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (data->cal_view));
if (GTK_IS_WINDOW (toplevel)) {
gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)), GTK_WINDOW (pevent->tooltip));
gtk_window_set_transient_for (GTK_WINDOW (pevent->tooltip), GTK_WINDOW (toplevel));
}
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type ((GtkFrame *) frame, GTK_SHADOW_IN);
......
......@@ -241,8 +241,8 @@ ecep_attachments_sensitize_widgets (ECompEditorPage *page,
page_attachments = E_COMP_EDITOR_PAGE_ATTACHMENTS (page);
gtk_widget_set_sensitive (page_attachments->priv->controls_container, !force_insensitive && is_organizer);
gtk_widget_set_sensitive (page_attachments->priv->notebook, !force_insensitive && is_organizer);
gtk_widget_set_sensitive (page_attachments->priv->controls_container, !force_insensitive);
gtk_widget_set_sensitive (page_attachments->priv->notebook, !force_insensitive);
action = e_comp_editor_get_action (comp_editor, "attachments-attach");
gtk_action_set_sensitive (action, !force_insensitive && is_organizer);
......@@ -664,6 +664,7 @@ static void
ecep_attachments_constructed (GObject *object)
{
ECompEditorPageAttachments *page_attachments;
ECompEditor *comp_editor;
GSettings *settings;
GtkSizeGroup *size_group;
GtkWidget *container;
......@@ -831,6 +832,21 @@ ecep_attachments_constructed (GObject *object)
g_clear_object (&settings);
ecep_attachments_setup_ui (page_attachments);
comp_editor = e_comp_editor_page_ref_editor (E_COMP_EDITOR_PAGE (page_attachments));
action = e_comp_editor_get_action (comp_editor, "attachments-attach");
e_binding_bind_property (
action, "sensitive",
e_attachment_view_get_action (E_ATTACHMENT_VIEW (page_attachments->priv->icon_view), "add"), "sensitive",
G_BINDING_SYNC_CREATE);
e_binding_bind_property (
action, "sensitive",
e_attachment_view_get_action (E_ATTACHMENT_VIEW (page_attachments->priv->tree_view), "add"), "sensitive",
G_BINDING_SYNC_CREATE);
g_clear_object (&comp_editor);
}
static void
......
......@@ -632,6 +632,7 @@ ecep_reminders_widgets_to_selected (ECompEditorPageReminders *page_reminders)
g_return_if_reached ();
}
} else {
memset (&repeat, 0, sizeof (repeat));
repeat.repetitions = 0;
}
......
......@@ -673,9 +673,12 @@ ece_save_component_attachments_sync (ECalClient *cal_client,
if (g_ascii_strncasecmp (uri, "file://", 7) == 0 &&
!g_str_has_prefix (uri + 7, target_filename_prefix)) {
GFile *source, *destination;
gchar *decoded_filename;
gchar *target_filename;
target_filename = g_strconcat (target_filename_prefix, strrchr (uri, '/') + 1, NULL);
decoded_filename = g_uri_unescape_string (strrchr (uri, '/') + 1, NULL);
target_filename = g_strconcat (target_filename_prefix, decoded_filename, NULL);
g_free (decoded_filename);
source = g_file_new_for_uri (uri);
destination = g_file_new_for_path (target_filename);
......
......@@ -7200,10 +7200,8 @@ cancel_editing (EDayView *day_view)
day = day_view->editing_event_day;
event_num = day_view->editing_event_num;
if (day == -1) {
g_warn_if_reached ();
if (day == -1)
return;
}
if (day == E_DAY_VIEW_LONG_EVENT) {
if (!is_array_index_in_bounds (day_view->long_events, event_num))
......
......@@ -33,6 +33,7 @@
#include "calendar-config.h"
#include "e-meeting-list-view.h"
#include "itip-utils.h"
#include <addressbook/util/eab-book-util.h>
#include <shell/e-shell.h>
#include "e-select-names-renderer.h"
......@@ -946,23 +947,27 @@ process_section (EMeetingListView *view,
for (l = list_dests; l; l = l->next) {
EDestination *dest = l->data;
EContact *contact;
const gchar *name, *attendee = NULL;
gchar *fburi = NULL;
const gchar *textrep;
gchar *fburi = NULL, *name = NULL, *email_addr = NULL;
name = e_destination_get_name (dest);
attendee = e_destination_get_email (dest);
textrep = e_destination_get_textrep (dest, TRUE);
if (!eab_parse_qp_email (textrep, &name, &email_addr))
email_addr = g_strdup (textrep);
if (attendee == NULL || *attendee == '\0')
if (!email_addr || !*email_addr) {
g_free (name);
g_free (email_addr);
continue;
}
contact = e_destination_get_contact (dest);
if (contact)
fburi = e_contact_get (contact, E_CONTACT_FREEBUSY_URL);
if (e_meeting_store_find_attendee (priv->store, attendee, NULL) == NULL) {
if (e_meeting_store_find_attendee (priv->store, email_addr, NULL) == NULL) {
EMeetingAttendee *ia = e_meeting_store_add_attendee_with_defaults (priv->store);
e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", attendee));
e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", email_addr));
e_meeting_attendee_set_role (ia, role);
if (role == ICAL_ROLE_NONPARTICIPANT)
e_meeting_attendee_set_cutype (ia, ICAL_CUTYPE_RESOURCE);
......@@ -977,10 +982,12 @@ process_section (EMeetingListView *view,
g_slist_free (*la);
*la = NULL;
} else
*la = g_slist_remove_link (*la, g_slist_find_custom (*la, attendee, (GCompareFunc)g_ascii_strcasecmp));
*la = g_slist_remove_link (*la, g_slist_find_custom (*la, email_addr, (GCompareFunc) g_ascii_strcasecmp));
}
g_free (name);
g_free (fburi);
g_free (email_addr);
}
if (des) {
......
......@@ -2384,6 +2384,15 @@ e_meeting_time_selector_recalc_date_format (EMeetingTimeSelector *mts)
longest_weekday = day;
longest_weekday_width = width;
}
/* Now try it with abbreviated weekday names. */
name = e_get_weekday_name (day, TRUE);
pango_layout_set_text (layout, name, -1);
pango_layout_get_pixel_size (layout, &width, NULL);
if (width > longest_weekday_width) {
longest_weekday = day;
longest_weekday_width = width;
}
}
/* Now find the biggest month name. */
......@@ -2399,19 +2408,6 @@ e_meeting_time_selector_recalc_date_format (EMeetingTimeSelector *mts)
}
}
/* Now try it with abbreviated weekday names. */
longest_weekday_width = 0;
longest_weekday = G_DATE_MONDAY;
for (day = G_DATE_MONDAY; day <= G_DATE_SUNDAY; day++) {
name = e_get_weekday_name (day, TRUE);
pango_layout_set_text (layout, name, -1);
pango_layout_get_pixel_size (layout, &width, NULL);
if (width > longest_weekday_width) {
longest_weekday = day;
longest_weekday_width = width;
}
}
g_date_set_dmy (
&date, days[longest_month - 1] + longest_weekday,
longest_month, 2000);
......
......@@ -394,7 +394,7 @@ memo_table_query_tooltip (GtkWidget *widget,
EMemoTable *memo_table;
ECalModel *model;
ECalModelComponent *comp_data;
gint row = -1, col = -1;
gint row = -1, col = -1, row_y = -1, row_height = -1;
GtkWidget *box, *l, *w;
GdkRGBA sel_bg, sel_fg, norm_bg, norm_text;
gchar *tmp;
......@@ -426,6 +426,9 @@ memo_table_query_tooltip (GtkWidget *widget,
if (esm && esm->sorter && e_sorter_needs_sorting (esm->sorter))
row = e_sorter_sorted_to_model (esm->sorter, row);
if (row < 0)
return FALSE;
model = e_memo_table_get_model (memo_table);
comp_data = e_cal_model_get_component_at (model, row);
if (!comp_data || !comp_data->icalcomp)
......@@ -608,6 +611,41 @@ memo_table_query_tooltip (GtkWidget *widget,
g_object_unref (new_comp);
if (esm && esm->sorter && e_sorter_needs_sorting (esm->sorter))
row = e_sorter_model_to_sorted (esm->sorter, row);
e_table_get_cell_geometry (E_TABLE (memo_table), row, 0, NULL, &row_y, NULL, &row_height);
if (row_y != -1 && row_height != -1) {
ETable *etable;
GdkRectangle rect;
GtkAllocation allocation;
etable = E_TABLE (memo_table);
if (etable && etable->table_canvas) {
gtk_widget_get_allocation (GTK_WIDGET (etable->table_canvas), &allocation);
} else {
allocation.x = 0;
allocation.y = 0;
allocation.width = 0;
allocation.height = 0;
}
rect.x = allocation.x;
rect.y = allocation.y + row_y - BUTTON_PADDING;
rect.width = allocation.width;
rect.height = row_height + 2 * BUTTON_PADDING;
if (etable && etable->header_canvas) {
gtk_widget_get_allocation (GTK_WIDGET (etable->header_canvas), &allocation);
rect.y += allocation.height;
}
gtk_tooltip_set_tip_area (tooltip, &rect);
}
return TRUE;
}
......
......@@ -696,7 +696,7 @@ task_table_query_tooltip (GtkWidget *widget,
ETaskTable *task_table;
ECalModel *model;
ECalModelComponent *comp_data;
gint row = -1, col = -1;
gint row = -1, col = -1, row_y = -1, row_height = -1;
GtkWidget *box, *l, *w;
GdkRGBA sel_bg, sel_fg, norm_bg, norm_text;
gchar *tmp;
......@@ -921,6 +921,41 @@ task_table_query_tooltip (GtkWidget *widget,
g_object_unref (new_comp);
if (esm && esm->sorter && e_sorter_needs_sorting (esm->sorter))
row = e_sorter_model_to_sorted (esm->sorter, row);
e_table_get_cell_geometry (E_TABLE (task_table), row, 0, NULL, &row_y, NULL, &row_height);
if (row_y != -1 && row_height != -1) {
ETable *etable;
GdkRectangle rect;
GtkAllocation allocation;
etable = E_TABLE (task_table);
if (etable && etable->table_canvas) {
gtk_widget_get_allocation (GTK_WIDGET (etable->table_canvas), &allocation);
} else {
allocation.x = 0;
allocation.y = 0;
allocation.width = 0;
allocation.height = 0;
}
rect.x = allocation.x;
rect.y = allocation.y + row_y - BUTTON_PADDING;
rect.width = allocation.width;
rect.height = row_height + 2 * BUTTON_PADDING;
if (etable && etable->header_canvas) {
gtk_widget_get_allocation (GTK_WIDGET (etable->header_canvas), &allocation);
rect.y += allocation.height;
}
gtk_tooltip_set_tip_area (tooltip, &rect);
}
return TRUE;
}
......
......@@ -159,7 +159,7 @@ week_view_main_item_draw_day (EWeekViewMainItem *main_item,
cr, &week_view->colors[E_WEEK_VIEW_COLOR_SELECTED]);
} else {
gdk_cairo_set_source_color (
cr, &week_view->colors[E_WEEK_VIEW_COLOR_SELECTED]);
cr, &week_view->colors[E_WEEK_VIEW_COLOR_SELECTED_UNFOCUSSED]);
}
if (multi_week_view) {
......
......@@ -275,7 +275,7 @@ e_composer_private_constructed (EMsgComposer *composer)
g_free (gallery_path);
e_signal_connect_notify_swapped (
view, "notify::mode",
view, "notify::html-mode",
G_CALLBACK (composer_update_gallery_visibility), composer);
g_signal_connect_swapped (
......@@ -799,27 +799,6 @@ use_top_signature (EMsgComposer *composer)
return top_signature;
}
static void
composer_size_allocate_cb (GtkWidget *widget,
gpointer user_data)
{
GtkWidget *scrolled_window;
GtkAdjustment *adj;
scrolled_window = gtk_widget_get_parent (GTK_WIDGET (widget));
adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window));
/* Scroll only when there is some size allocated */
if (gtk_adjustment_get_upper (adj) != 0.0) {
/* Scroll web view down to caret */
gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj) - gtk_adjustment_get_page_size (adj));
gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window), adj);
/* Disconnect because we don't want to scroll down the view on every window size change */
g_signal_handlers_disconnect_by_func (
widget, G_CALLBACK (composer_size_allocate_cb), NULL);
}
}
static WebKitDOMElement *
prepare_paragraph (EHTMLEditorSelection *selection,
WebKitDOMDocument *document)
......@@ -1037,15 +1016,10 @@ composer_move_caret (EMsgComposer *composer)
g_clear_object (&dom_selection);
g_clear_object (&dom_window);
g_clear_object (&range);
if (start_bottom)
e_html_editor_selection_scroll_to_caret (editor_selection);
}
if (start_bottom)
g_signal_connect (
view, "size-allocate",
G_CALLBACK (composer_size_allocate_cb), NULL);
e_html_editor_selection_scroll_to_caret (editor_selection);
e_html_editor_view_force_spell_check_in_viewport (view);
......@@ -1067,7 +1041,7 @@ composer_load_signature_cb (EMailSignatureComboBox *combo_box,
WebKitDOMDocument *document;
WebKitDOMElement *signature_to_insert;
WebKitDOMElement *insert_signature_in = NULL;
WebKitDOMElement *signature_wrapper;
WebKitDOMElement *signature_wrapper = NULL;
WebKitDOMElement *element, *converted_signature = NULL;
WebKitDOMHTMLElement *body;
WebKitDOMNodeList *signatures;
......@@ -1101,6 +1075,7 @@ composer_load_signature_cb (EMailSignatureComboBox *combo_box,
/* Create the DOM signature that is the same across all types of signatures. */
document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
body = webkit_dom_document_get_body (document);
signature_to_insert = webkit_dom_document_create_element (document, "span", NULL);
webkit_dom_element_set_class_name (signature_to_insert, "-x-evo-signature");
/* The combo box active ID is the signature's ESource UID. */
......@@ -1108,6 +1083,8 @@ composer_load_signature_cb (EMailSignatureComboBox *combo_box,
signature_to_insert, gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box)));
insert_signature_in = signature_to_insert;
html_mode = e_html_editor_view_get_html_mode (view);
/* The signature has no content usually it means it is set to None. */
if (!contents)
goto insert;
......@@ -1131,7 +1108,6 @@ composer_load_signature_cb (EMailSignatureComboBox *combo_box,
}
/* If inserting HTML signature in plain text composer we have to convert it. */
html_mode = e_html_editor_view_get_html_mode (view);
if (is_html && !html_mode && !strstr (contents, "data-evo-signature-plain-text-mode")) {
gchar *inner_text;
......@@ -1170,9 +1146,19 @@ composer_load_signature_cb (EMailSignatureComboBox *combo_box,
; /* skip */
else if (e_util_strstrcase (contents, delim_nl) != NULL)
; /* skip */
else
else {
WebKitDOMElement *pre_delimiter;
pre_delimiter = webkit_dom_document_create_element (document, "pre", NULL);
/* Always use the HTML delimiter as we are never in anything
* like a strict plain text mode. */
webkit_dom_html_element_set_inner_html (
WEBKIT_DOM_HTML_ELEMENT (insert_signature_in), delim, NULL);
WEBKIT_DOM_HTML_ELEMENT (pre_delimiter), "-- <br>", NULL);
webkit_dom_node_append_child (
WEBKIT_DOM_NODE (insert_signature_in),
WEBKIT_DOM_NODE (pre_delimiter),
NULL);
}
}
if (converted_signature) {
......@@ -1210,7 +1196,7 @@ insert:
/* When we are editing a message with signature, we need to unset the
* active signature id as if the signature in the message was edited
* by the user we would discard these changes. */
if (composer->priv->set_signature_from_message &&
if (composer->priv->set_signature_from_message && contents &&
(is_message_from_edit_as_new || e_html_editor_view_is_message_from_draft (view))) {
if (composer->priv->check_if_signature_is_changed) {
/* Normalize the signature that we want to insert as the one in the
......@@ -1255,55 +1241,82 @@ insert:
if (spacer)
remove_node_if_empty (WEBKIT_DOM_NODE (spacer));
}
/* We have to remove the div containing the span with signature */
remove_node (wrapper);
g_object_unref (wrapper);
/* Leave just one signature wrapper there as it will be reused. */
if (ii != list_length - 1) {
g_object_unref (wrapper);
remove_node (wrapper);
} else {
remove_node (signature);
signature_wrapper = WEBKIT_DOM_ELEMENT (wrapper);
}
}
g_object_unref (signatures);
body = webkit_dom_document_get_body (document);
signature_wrapper = webkit_dom_document_create_element (document, "div", NULL);
webkit_dom_node_append_child (
WEBKIT_DOM_NODE (signature_wrapper),
WEBKIT_DOM_NODE (signature_to_insert),
NULL);
webkit_dom_element_set_class_name (signature_wrapper, "-x-evo-signature-wrapper");
if (top_signature) {
GSettings *settings;
WebKitDOMNode *child;
if (signature_wrapper) {
webkit_dom_node_append_child (
WEBKIT_DOM_NODE (signature_wrapper),
WEBKIT_DOM_NODE (signature_to_insert),
NULL);
child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
/* Insert a spacer below the top signature */
if (top_signature && contents) {
WebKitDOMElement *spacer;
EHTMLEditorSelection *editor_selection;
settings = e_util_ref_settings ("org.gnome.evolution.mail");
if (g_settings_get_boolean (settings, "composer-reply-start-bottom")) {
editor_selection = e_html_editor_view_get_selection (view);
spacer = prepare_top_signature_spacer (editor_selection, document);
webkit_dom_node_insert_before (
WEBKIT_DOM_NODE (body),
WEBKIT_DOM_NODE (signature_wrapper),
child,
NULL);
} else {
/* When we are using signature on top the caret
* should be before the signature */
webkit_dom_node_insert_before (
WEBKIT_DOM_NODE (body),
WEBKIT_DOM_NODE (signature_wrapper),
child,
WEBKIT_DOM_NODE (spacer),
webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (signature_wrapper)),
NULL);
}
g_object_unref (settings);
g_object_unref (signature_wrapper);
} else {
signature_wrapper = webkit_dom_document_create_element (document, "div", NULL);
webkit_dom_element_set_class_name (signature_wrapper, "-x-evo-signature-wrapper");
webkit_dom_node_append_child (
WEBKIT_DOM_NODE (body),
WEBKIT_DOM_NODE (signature_wrapper),
WEBKIT_DOM_NODE (signature_to_insert),
NULL);
if (top_signature) {
GSettings *settings;
WebKitDOMNode *child;
child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body));
settings = e_util_ref_settings ("org.gnome.evolution.mail");
if (g_settings_get_boolean (settings, "composer-reply-start-bottom")) {
webkit_dom_node_insert_before (
WEBKIT_DOM_NODE (body),
WEBKIT_DOM_NODE (signature_wrapper),
child,
NULL);
} else {
/* When we are using signature on top the caret
* should be before the signature */
webkit_dom_node_insert_before (
WEBKIT_DOM_NODE (body),
WEBKIT_DOM_NODE (signature_wrapper),
child,
NULL);
}
g_object_unref (settings);
} else {
webkit_dom_node_append_child (
WEBKIT_DOM_NODE (body),
WEBKIT_DOM_NODE (signature_wrapper),
NULL);
}
composer_move_caret (composer);
}
g_object_unref (signatures);
if (is_html && html_mode)
e_html_editor_view_fix_file_uri_images (view);
composer_move_caret (composer);
exit:
/* Make sure the flag will be unset and won't influence user's choice */
composer->priv->set_signature_from_message = FALSE;
......
......@@ -1340,13 +1340,6 @@ composer_build_message (EMsgComposer *composer,
data = g_byte_array_new ();
if ((flags & COMPOSER_FLAG_SAVE_DRAFT) != 0) {
EHTMLEditorSelection *selection;
gboolean selection_saved = FALSE;
WebKitDOMDocument *document;
selection = e_html_editor_view_get_selection (view);
document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
/* X-Evolution-Format */
composer_add_evolution_format_header (
CAMEL_MEDIUM (context->message), flags);
......@@ -1355,26 +1348,12 @@ composer_build_message (EMsgComposer *composer,
composer_add_evolution_composer_mode_header (
CAMEL_MEDIUM (context->message), composer);
e_html_editor_view_embed_styles (view);
selection_saved = webkit_dom_document_get_element_by_id (
document, "-x-evo-selection-start-marker") != NULL;
if (!selection_saved)
e_html_editor_selection_save (selection);
text = e_html_editor_view_get_text_html_for_drafts (view);
e_html_editor_view_remove_embed_styles (view);
e_html_editor_selection_restore (selection);
e_html_editor_view_force_spell_check_in_viewport (view);
if (selection_saved)
e_html_editor_selection_save (selection);
length = strlen (text);
} else {
text = e_html_editor_view_get_text_html_for_drafts_with_images (
view, from_domain, &inline_images);
} else
text = e_html_editor_view_get_text_html (view, from_domain, &inline_images);
length = strlen (text);
}
length = strlen (text);
g_byte_array_append (data, (guint8 *) text, (guint) length);
pre_encode = text_requires_quoted_printable (text, length);
g_free (text);
......@@ -1595,12 +1574,13 @@ static void
attachment_store_changed_cb (EMsgComposer *composer)
{
EHTMLEditor *editor;
EHTMLEditorView *view;
/* Mark the editor as changed so it prompts about unsaved
* changes on close. */
editor = e_msg_composer_get_editor (composer);
if (editor) {
EHTMLEditorView *view;
view = e_html_editor_get_view (editor);
e_html_editor_view_set_changed (view, TRUE);
}
......@@ -2335,29 +2315,12 @@ msg_composer_notify_header_cb (EMsgComposer *composer)
static gboolean
msg_composer_delete_event_cb (EMsgComposer *composer)
{
EShell *shell;
GtkApplication *application;
GList *windows;
shell = e_msg_composer_get_shell (composer);
/* If the "async" action group is insensitive, it means an
* asynchronous operation is in progress. Block the event. */
if (!gtk_action_group_get_sensitive (composer->priv->async_actions))
return TRUE;
application = GTK_APPLICATION (shell);
windows = gtk_application_get_windows (application);
if (g_list_length (windows) == 1) {
/* This is the last watched window, use the quit
* mechanism to have a draft saved properly */
e_shell_quit (shell, E_SHELL_QUIT_ACTION);
} else {
/* There are more watched windows opened,
* invoke only a close action */
gtk_action_activate (ACTION (CLOSE));
}
gtk_action_activate (ACTION (CLOSE));
return TRUE;
}
......@@ -4068,7 +4031,7 @@ e_msg_composer_new_with_message (EShell *shell,
g_strdup (headers->name));
g_ptr_array_add (
composer->priv->extra_hdr_values,
g_strdup (headers->value));
camel_header_unfold (headers->value));
}
headers = headers->next;
......@@ -4352,6 +4315,29 @@ e_msg_composer_send (EMsgComposer *composer)
context);
}
static void
msg_composer_save_to_drafts_done_cb (gpointer user_data,
GObject *gone_object)
{
EMsgComposer *composer = user_data;
EHTMLEditor *editor;
EHTMLEditorView *view;
g_return_if_fail (E_IS_MSG_COMPOSER (composer));
editor = e_msg_composer_get_editor (composer);
view = e_html_editor_get_view (editor);
if (e_msg_composer_is_exiting (composer) &&
!e_html_editor_view_get_changed (view)) {
gtk_widget_destroy (GTK_WIDGET (composer));
} else if (e_msg_composer_is_exiting (composer)) {
gtk_widget_set_sensitive (GTK_WIDGET (composer), TRUE);
gtk_window_present (GTK_WINDOW (composer));
composer->priv->application_exiting = FALSE;
}
}
static void
msg_composer_save_to_drafts_cb (EMsgComposer *composer,
GAsyncResult *result,
......@@ -4414,7 +4400,7 @@ msg_composer_save_to_drafts_cb (EMsgComposer *composer,
if (e_msg_composer_is_exiting (composer))
g_object_weak_ref (
G_OBJECT (context->activity),
(GWeakNotify) gtk_widget_destroy, composer);
msg_composer_save_to_drafts_done_cb, composer);
async_context_free (context);
}
......@@ -5711,7 +5697,6 @@ e_msg_composer_can_close (EMsgComposer *composer,
switch (response) {
case GTK_RESPONSE_YES:
gtk_widget_hide (widget);
e_msg_composer_request_close (composer);
if (can_save_draft)
gtk_action_activate (ACTION (SAVE_DRAFT));
......
dnl Evolution Versions
m4_define([evo_major_version], [3])
m4_define([evo_minor_version], [20])
m4_define([evo_micro_version], [0])
m4_define([evo_micro_version], [6])
m4_define([evo_version],
[evo_major_version.evo_minor_version.evo_micro_version])
m4_define([evo_stable_version],
......
......@@ -482,10 +482,44 @@ attachment_bar_update_actions (EAttachmentView *view)
e_attachment_view_update_actions (view);
}
static gboolean
attachment_bar_button_press_event (GtkWidget *widget,
GdkEventButton *event)
{
/* Chain up to parent's button_press_event() method. */
GTK_WIDGET_CLASS (e_attachment_bar_parent_class)->button_press_event (widget, event);
/* Never propagate the event to the parent */
return TRUE;
}
static gboolean
attachment_bar_button_release_event (GtkWidget *widget,
GdkEventButton *event)
{
/* Chain up to parent's button_release_event() method. */
GTK_WIDGET_CLASS (e_attachment_bar_parent_class)->button_release_event (widget, event);
/* Never propagate the event to the parent */
return TRUE;
}
static gboolean
attachment_bar_motion_notify_event (GtkWidget *widget,
GdkEventMotion *event)
{
/* Chain up to parent's motion_notify_event() method. */
GTK_WIDGET_CLASS (e_attachment_bar_parent_class)->motion_notify_event (widget, event);
/* Never propagate the event to the parent */
return TRUE;
}
static void
e_attachment_bar_class_init (EAttachmentBarClass *class)
{
GObjectClass *object_class;
GtkWidgetClass *widget_class;
g_type_class_add_private (class, sizeof (EAttachmentBarPrivate));
......@@ -495,6 +529,11 @@ e_attachment_bar_class_init (EAttachmentBarClass *class)
object_class->dispose = attachment_bar_dispose;
object_class->constructed = attachment_bar_constructed;
widget_class = GTK_WIDGET_CLASS (class);
widget_class->button_press_event = attachment_bar_button_press_event;
widget_class->button_release_event = attachment_bar_button_release_event;
widget_class->motion_notify_event = attachment_bar_motion_notify_event;
g_object_class_install_property (
object_class,
PROP_ACTIVE_VIEW,
......@@ -624,6 +663,7 @@ e_attachment_bar_init (EAttachmentBar *bar)
widget = gtk_expander_new (NULL);
gtk_expander_set_spacing (GTK_EXPANDER (widget), 0);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
bar->priv->expander = g_object_ref (widget);
gtk_widget_show (widget);
......
......@@ -140,6 +140,8 @@ attachment_icon_view_constructed (GObject *object)
/* Chain up to parent's method. */
G_OBJECT_CLASS (e_attachment_icon_view_parent_class)->constructed (object);
gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (object), GTK_SELECTION_MULTIPLE);
cell_layout = GTK_CELL_LAYOUT (object);
/* This needs to happen after constructor properties are set
......@@ -546,9 +548,6 @@ e_attachment_icon_view_init (EAttachmentIconView *icon_view)
icon_view->priv = E_ATTACHMENT_ICON_VIEW_GET_PRIVATE (icon_view);
e_attachment_view_init (E_ATTACHMENT_VIEW (icon_view));
gtk_icon_view_set_selection_mode (
GTK_ICON_VIEW (icon_view), GTK_SELECTION_MULTIPLE);
}
static void
......
......@@ -59,6 +59,27 @@ G_DEFINE_TYPE_WITH_CODE (
G_IMPLEMENT_INTERFACE (
E_TYPE_EXTENSIBLE, NULL))
static void
attachment_tree_view_render_size (GtkTreeViewColumn *column,
GtkCellRenderer *renderer,
GtkTreeModel *model,
GtkTreeIter *iter)
{
gchar *display_size = NULL;
gint column_id;
guint64 size;
column_id = E_ATTACHMENT_STORE_COLUMN_SIZE;
gtk_tree_model_get (model, iter, column_id, &size, -1);
if (size > 0)
display_size = g_format_size ((goffset) size);
g_object_set (renderer, "text", display_size, NULL);
g_free (display_size);
}
static void
attachment_tree_view_set_property (GObject *object,
guint property_id,
......@@ -105,6 +126,97 @@ attachment_tree_view_get_property (GObject *object,
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
attachment_tree_view_constructed (GObject *object)
{
EAttachmentTreeView *tree_view = E_ATTACHMENT_TREE_VIEW (object);
GtkTreeSelection *selection;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
/* Chain up to parent's method. */
G_OBJECT_CLASS (e_attachment_tree_view_parent_class)->constructed (object);
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
/* Name Column */
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_expand (column, TRUE);
gtk_tree_view_column_set_spacing (column, 3);
gtk_tree_view_column_set_title (column, _("Description"));
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
renderer = gtk_cell_renderer_pixbuf_new ();
gtk_tree_view_column_pack_start (column, renderer, FALSE);
g_object_set (renderer, "stock-size", GTK_ICON_SIZE_MENU, NULL);
gtk_tree_view_column_add_attribute (
column, renderer, "gicon",
E_ATTACHMENT_STORE_COLUMN_ICON);
renderer = gtk_cell_renderer_text_new ();
g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
gtk_tree_view_column_pack_start (column, renderer, TRUE);
gtk_tree_view_column_add_attribute (
column, renderer, "text",
E_ATTACHMENT_STORE_COLUMN_DESCRIPTION);
renderer = gtk_cell_renderer_progress_new ();
g_object_set (renderer, "text", _("Loading"), NULL);
gtk_tree_view_column_pack_start (column, renderer, TRUE);
gtk_tree_view_column_add_attribute (
column, renderer, "value",
E_ATTACHMENT_STORE_COLUMN_PERCENT);
gtk_tree_view_column_add_attribute (
column, renderer, "visible",
E_ATTACHMENT_STORE_COLUMN_LOADING);
renderer = gtk_cell_renderer_progress_new ();
g_object_set (renderer, "text", _("Saving"), NULL);
gtk_tree_view_column_pack_start (column, renderer, TRUE);
gtk_tree_view_column_add_attribute (
column, renderer, "value",
E_ATTACHMENT_STORE_COLUMN_PERCENT);
gtk_tree_view_column_add_attribute (
column, renderer, "visible",
E_ATTACHMENT_STORE_COLUMN_SAVING);
/* Size Column */
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_title (column, _("Size"));
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func (
column, renderer, (GtkTreeCellDataFunc)
attachment_tree_view_render_size, NULL, NULL);
/* Type Column */
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_title (column, _("Type"));
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer, TRUE);
gtk_tree_view_column_add_attribute (
column, renderer, "text",
E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE);
e_extensible_load_extensions (E_EXTENSIBLE (tree_view));
}
static void
attachment_tree_view_dispose (GObject *object)
{
......@@ -123,27 +235,6 @@ attachment_tree_view_finalize (GObject *object)
G_OBJECT_CLASS (e_attachment_tree_view_parent_class)->finalize (object);
}
static void
attachment_tree_view_render_size (GtkTreeViewColumn *column,
GtkCellRenderer *renderer,
GtkTreeModel *model,
GtkTreeIter *iter)
{
gchar *display_size = NULL;
gint column_id;
guint64 size;
column_id = E_ATTACHMENT_STORE_COLUMN_SIZE;
gtk_tree_model_get (model, iter, column_id, &size, -1);
if (size > 0)
display_size = g_format_size ((goffset) size);
g_object_set (renderer, "text", display_size, NULL);
g_free (display_size);
}
static gboolean
attachment_tree_view_button_press_event (GtkWidget *widget,