Commit ba81ad43 authored by Jim Nelson's avatar Jim Nelson

Prettier dates and From: labels. Initial GMime integration.

This adds a VAPI (including generation files and Makefile) for GMime to the repo, which we'll be using extensively to come.  This VAPI is incomplete in many ways, so care should be used going forward.

Also, with GMime now interpreting RFC822 dates, can now pretty-print them.  Prettier From: names also added this time around.
parent a581218e
......@@ -2,7 +2,7 @@ PROGRAM = geary
BUILD_ROOT = 1
VALAC := valac
VALAFLAGS := -g --save-temps --enable-checking --fatal-warnings
VALAFLAGS := -g --save-temps --enable-checking --fatal-warnings --vapidir=vapi
APPS := geary console syntax lsmbox readmail watchmbox
......@@ -49,7 +49,8 @@ CLIENT_SRC := \
src/client/ui/MainWindow.vala \
src/client/ui/MessageListView.vala \
src/client/ui/MessageListStore.vala \
src/client/util/Intl.vala
src/client/util/Intl.vala \
src/client/util/Date.vala
CONSOLE_SRC := \
src/console/main.vala
......@@ -73,7 +74,11 @@ EXTERNAL_PKGS := \
gee-1.0 \
gtk+-2.0 \
unique-1.0 \
posix
posix \
gmime-2.4
VAPI_FILES := \
vapi/gmime-2.4.vapi
.PHONY: all
all: $(APPS)
......@@ -83,7 +88,7 @@ clean:
rm -f $(ALL_SRC:.vala=.c)
rm -f $(APPS)
geary: $(ENGINE_SRC) $(CLIENT_SRC) Makefile
geary: $(ENGINE_SRC) $(CLIENT_SRC) Makefile $(VAPI_FILES)
$(VALAC) $(VALAFLAGS) $(foreach pkg,$(EXTERNAL_PKGS),--pkg=$(pkg)) \
$(ENGINE_SRC) $(CLIENT_SRC) \
-o $@
......
......@@ -10,22 +10,50 @@ public class MessageListStore : Gtk.TreeStore {
FROM,
SUBJECT,
N_COLUMNS;
public static Column[] all() {
return {
DATE,
FROM,
SUBJECT
};
}
public static Type[] get_types() {
return {
typeof (string), // DATE
typeof (string), // FROM
typeof (string) // SUBJECT
};
}
public string to_string() {
switch (this) {
case DATE:
return _("Date");
case FROM:
return _("From");
case SUBJECT:
return _("Subject");
default:
assert_not_reached();
}
}
}
public MessageListStore() {
set_column_types({
typeof (string), // DATE
typeof (string), // FROM
typeof (string) // SUBJECT
});
set_column_types(Column.get_types());
}
public void append_message(Geary.Message msg) {
Gtk.TreeIter iter;
append(out iter, null);
set(iter, Column.DATE, msg.sent.value, Column.FROM, msg.from.get_at(0).get_full_address(),
Column.SUBJECT, msg.subject.value);
set(iter, Column.DATE, Date.pretty_print(msg.sent.value), Column.FROM,
msg.from.get_at(0).get_short_address(), Column.SUBJECT, msg.subject.value);
}
}
......@@ -8,15 +8,19 @@ public class MessageListView : Gtk.TreeView {
public MessageListView(MessageListStore store) {
set_model(store);
append_column(create_text_column(MessageListStore.Column.DATE, _("Date")));
append_column(create_text_column(MessageListStore.Column.FROM, _("From")));
append_column(create_text_column(MessageListStore.Column.SUBJECT, _("Subject")));
Gtk.CellRendererText date_renderer = new Gtk.CellRendererText();
date_renderer.xalign = 1.0f;
append_column(create_column(MessageListStore.Column.FROM, new Gtk.CellRendererText(),
"text", 200));
append_column(create_column(MessageListStore.Column.SUBJECT, new Gtk.CellRendererText(),
"text", 400));
append_column(create_column(MessageListStore.Column.DATE, date_renderer, "text", 100));
}
private Gtk.TreeViewColumn create_text_column(int column, string name, int width = 0,
Gtk.CellRendererText? renderer = null) {
Gtk.TreeViewColumn view_column = new Gtk.TreeViewColumn.with_attributes(name,
(renderer != null) ? renderer : new Gtk.CellRendererText(), "text", column);
private static Gtk.TreeViewColumn create_column(MessageListStore.Column column,
Gtk.CellRenderer renderer, string attr, int width = 0) {
Gtk.TreeViewColumn view_column = new Gtk.TreeViewColumn.with_attributes(column.to_string(),
renderer, attr, column);
view_column.set_resizable(true);
if (width != 0) {
......
/* Copyright 2011 Yorba Foundation
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
namespace Date {
public bool equals(DateTime a, DateTime b) {
int year1, month1, day1;
a.get_ymd(out year1, out month1, out day1);
int year2, month2, day2;
b.get_ymd(out year2, out month2, out day2);
return year1 == year2 && month1 == month2 && day1 == day2;
}
public string pretty_print(DateTime datetime) {
DateTime now = new DateTime.now_local();
string fmt;
if (equals(datetime, now)) {
// 8:31 am
fmt = "%l:%M %P";
} else if (datetime.get_year() == now.get_year()) {
// Nov 8
fmt = "%b %e";
} else {
// 02/04/10
fmt = "%m/%e/%y";
}
return datetime.format(fmt);
}
}
......@@ -101,8 +101,8 @@ public class Geary.Imap.Flags : Geary.Common.MessageData, Geary.Imap.MessageData
}
public class Geary.Imap.InternalDate : Geary.RFC822.Date, Geary.Imap.MessageData {
public InternalDate(string value) {
base (value);
public InternalDate(string iso8601) throws ImapError {
base (iso8601);
}
}
......
......@@ -117,7 +117,8 @@ public class Geary.Imap.EnvelopeDecoder : Geary.Imap.FetchDataDecoder {
StringParameter? in_reply_to = listp.get_as_nullable_string(8);
StringParameter message_id = listp.get_as_string(9);
return new Envelope(new Geary.RFC822.Date(sent.value), new Geary.RFC822.Subject(subject.value),
return new Envelope(new Geary.RFC822.Date(sent.value),
new Geary.RFC822.Subject(subject.value),
parse_addresses(from), parse_addresses(sender), parse_addresses(reply_to),
(to != null) ? parse_addresses(to) : null,
(cc != null) ? parse_addresses(cc) : null,
......
......@@ -62,6 +62,8 @@ public class Geary.Imap.FetchResults {
array += decode_data(data);
} catch (ImapError ierr) {
// drop bad data on the ground
debug("Dropping FETCH data \"%s\": %s", data.to_string(), ierr.message);
continue;
}
}
......
......@@ -28,6 +28,14 @@ public class Geary.RFC822.MailboxAddress {
return String.is_empty(name) ? "<%s>".printf(address) : "%s <%s>".printf(name, address);
}
/**
* Returns a human-readable pretty address, showing only the name, but if unavailable, the
* mailbox name (that is, the account name without the domain).
*/
public string get_short_address() {
return name ?? mailbox;
}
public string to_string() {
return get_full_address();
}
......
......@@ -19,9 +19,21 @@ public class Geary.RFC822.MessageID : Geary.Common.StringMessageData, Geary.RFC8
}
}
public class Geary.RFC822.Date : Geary.Common.StringMessageData, Geary.RFC822.MessageData {
public Date(string value) {
base (value);
public class Geary.RFC822.Date : Geary.RFC822.MessageData, Geary.Common.MessageData {
public string original { get; private set; }
public DateTime value { get; private set; }
public Date(string iso8601) throws ImapError {
time_t tm = GMime.utils_header_decode_date(iso8601, null);
if (tm == 0)
throw new ImapError.PARSE_ERROR("Unable to parse \"%s\": not ISO-8601 date", iso8601);
value = new DateTime.from_unix_utc(tm);
original = iso8601;
}
public override string to_string() {
return original;
}
}
......
# NOTE: The dependencies in this file require vapigen and vala-gen-introspect to be installed,
# which are not default in a standard Vala installation.
GMIME_FILES := \
gmime-2.4/gmime-2.4.defines \
gmime-2.4/gmime-2.4.files \
gmime-2.4/gmime-2.4.metadata \
gmime-2.4/gmime-2.4.namespace
all: gmime-2.4.vapi
.PHONY: clean
clean:
rm gmime-2.4.vapi gmime-2.4/gmime-2.4.gi
gmime-2.4/gmime-2.4.gi: $(GMIME_FILES)
vala-gen-introspect gmime-2.4 gmime-2.4
gmime-2.4.vapi: gmime-2.4/gmime-2.4.gi
vapigen --pkg=glib-2.0 --pkg=gio-2.0 --library gmime-2.4 gmime-2.4/gmime-2.4.gi
This diff is collapsed.
include/gmime-2.4/
lib/libgmime-2.4.so
GMime cheader_filename="gmime/gmime.h" lower_case_cprefix="g_mime_"
g_mime_message_get_date.date is_out="1"
g_mime_message_get_date.tz_offset is_out="1"
g_mime_param_next name="get_next"
g_mime_signer_next name="get_next"
g_mime_utils_header_decode_date type_name="time_t"
g_mime_utils_header_decode_date.tz_offset is_out="1" nullable="1"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment