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.
This commit is contained in:
Jim Nelson 2011-05-26 17:29:00 -07:00
parent a581218ea9
commit ba81ad43a4
15 changed files with 1168 additions and 24 deletions

View file

@ -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 $@

View file

@ -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);
}
}

View file

@ -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) {

37
src/client/util/Date.vala Normal file
View file

@ -0,0 +1,37 @@
/* 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);
}
}

View file

@ -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);
}
}

View file

@ -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,

View file

@ -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;
}
}

View file

@ -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();
}

View file

@ -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;
}
}

21
vapi/Makefile Normal file
View file

@ -0,0 +1,21 @@
# 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

1014
vapi/gmime-2.4.vapi Normal file

File diff suppressed because it is too large Load diff

View file

View file

@ -0,0 +1,2 @@
include/gmime-2.4/
lib/libgmime-2.4.so

View file

@ -0,0 +1,9 @@
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"

View file

@ -0,0 +1 @@
GMime