Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ executable(
'src/MainWindow.vala',
'src/IndividualView.vala',
'src/Widgets/ContactRow.vala',
'src/Widgets/NameGroup.vala',
'src/Widgets/EmailGroup/EmailGroup.vala',
'src/Widgets/EmailGroup/EmailGroupRow.vala',
dependencies: [
dependency('folks'),
dependency('glib-2.0'),
Expand Down
84 changes: 76 additions & 8 deletions src/IndividualView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,104 @@
*
*/

public class Friends.IndividualView : Gtk.Grid {
public class Friends.IndividualView : Gtk.Box {
public Folks.Individual? individual { get; set; }

private Gtk.Button edit_button;
private Gtk.ActionBar edit_action_bar;
private NameGroup name_group;
private EmailGroup email_group;

construct {
var placeholder = new Granite.Placeholder (_("No Contact Selected"));
edit_button = new Gtk.Button.from_icon_name ("document-edit") {
visible = false
};

var individual_name = new Gtk.Label (null) {
ellipsize = Pango.EllipsizeMode.MIDDLE,
var header = new Gtk.HeaderBar () {
show_title_buttons = false,
title_widget = new Gtk.Grid ()
};
header.add_css_class (Granite.STYLE_CLASS_FLAT);
header.pack_end (new Gtk.WindowControls (END));
header.pack_end (edit_button);

var placeholder = new Granite.Placeholder (_("No Contact Selected")) {
hexpand = true,
vexpand = true
};
individual_name.add_css_class (Granite.STYLE_CLASS_H3_LABEL);

name_group = new NameGroup () {
hexpand = true
};

email_group = new EmailGroup ();

var details_grid = new Gtk.Grid ();
details_grid.attach (individual_name, 0, 0);
details_grid.attach (name_group, 0, 1);
details_grid.attach (email_group, 0, 2);

var cancel_button = new Gtk.Button.with_label (_("Cancel"));

var save_button = new Gtk.Button.with_label (_("Apply"));

edit_action_bar = new Gtk.ActionBar () {
revealed = false
};
edit_action_bar.pack_end (save_button);
edit_action_bar.pack_end (cancel_button);

var stack = new Gtk.Stack ();
stack.add_child (placeholder);
stack.add_child (details_grid);

attach (stack, 0, 0);
orientation = VERTICAL;
append (header);
append (stack);
append (edit_action_bar);
add_css_class (Granite.STYLE_CLASS_VIEW);

notify["individual"].connect (() => {
if (individual != null) {
stack.visible_child = details_grid;
edit_button.visible = true;

individual_name.label = individual.display_name;
update_groups.begin ();
} else {
stack.visible_child = placeholder;
edit_button.visible = false;
}
});

edit_button.clicked.connect (() => {
name_group.start_edit ();
email_group.start_edit ();
edit_button.visible = false;
edit_action_bar.revealed = true;
});

cancel_button.clicked.connect (() => finish_edit (false));

save_button.clicked.connect (() => finish_edit (true));
}

private async void update_groups () {
try {
name_group.name_details = (Folks.NameDetails) yield Folks.IndividualAggregator.dup ().ensure_individual_property_writeable (individual, "full-name");
} catch (Error e) {
warning ("Failed to get EmailDetails: %s", e.message);
}

try {
email_group.email_details = (Folks.EmailDetails) yield Folks.IndividualAggregator.dup ().ensure_individual_property_writeable (individual, "email-addresses");
} catch (Error e) {
warning ("Failed to get EmailDetails: %s", e.message);
}
}

private void finish_edit (bool save) {
name_group.finish_edit.begin (save);
email_group.finish_edit.begin (save);
edit_button.visible = true;
edit_action_bar.revealed = false;
}
}
16 changes: 1 addition & 15 deletions src/MainWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,6 @@ public class Friends.MainWindow : Gtk.ApplicationWindow {
sidebar_header.add_css_class ("titlebar");
sidebar_header.add_css_class (Granite.STYLE_CLASS_FLAT);

var individualview_header = new Gtk.WindowHandle () {
child = new Gtk.WindowControls (Gtk.PackType.END) {
halign = Gtk.Align.END
}
};
individualview_header.add_css_class (Granite.STYLE_CLASS_DEFAULT_DECORATION);
individualview_header.add_css_class ("titlebar");
individualview_header.add_css_class (Granite.STYLE_CLASS_FLAT);

search_entry = new Gtk.SearchEntry () {
margin_start = 9,
margin_end = 9,
Expand Down Expand Up @@ -81,16 +72,11 @@ public class Friends.MainWindow : Gtk.ApplicationWindow {

var individual_view = new Friends.IndividualView ();

var individual_grid = new Gtk.Grid ();
individual_grid.add_css_class (Granite.STYLE_CLASS_VIEW);
individual_grid.attach (individualview_header, 0, 0);
individual_grid.attach (individual_view, 0, 1);

var paned = new Gtk.Paned (Gtk.Orientation.HORIZONTAL) {
start_child = sidebar_grid,
resize_start_child = false,
shrink_start_child = false,
end_child = individual_grid,
end_child = individual_view,
resize_end_child = true,
shrink_end_child = false
};
Expand Down
57 changes: 57 additions & 0 deletions src/Widgets/EmailGroup/EmailGroup.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
public class EmailGroup : Gtk.Box {
public Folks.EmailDetails email_details { get; set; }

private ListStore list_store;

construct {
list_store = new ListStore (typeof (EmailGroupRow));

var header_label = new Granite.HeaderLabel (_("E-Mail Adresses"));

var list_box = new Gtk.ListBox ();
list_box.bind_model (list_store, (item) => {
return (Gtk.ListBoxRow)item;
});

hexpand = true;
halign = CENTER;
orientation = VERTICAL;
append (header_label);
append (list_box);

notify["email-details"].connect (() => {
list_store.remove_all ();
foreach (var email_address in email_details.email_addresses) {
list_store.append (new EmailGroupRow (email_address));
}
});
}

public void start_edit () {
for (int i = 0; i < list_store.get_n_items (); i++) {
var email_group_row = (EmailGroupRow)list_store.get_item (i);
email_group_row.start_edit ();
}
}

public async void finish_edit (bool save) {
var new_set = new Gee.TreeSet<Folks.EmailFieldDetails> ();

for (int i = 0; i < list_store.get_n_items (); i++) {
var email_group_row = (EmailGroupRow)list_store.get_item (i);
email_group_row.finish_edit (save);

if (save) {
new_set.add (email_group_row.email_field_details);
}
}

if (save) {
try {
yield email_details.change_email_addresses (new_set);
} catch (Error e) {
warning ("Failed to update email addresses: %s", e.message);
}
}
}
}
42 changes: 42 additions & 0 deletions src/Widgets/EmailGroup/EmailGroupRow.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
public class EmailGroupRow : Gtk.ListBoxRow {
public Folks.EmailFieldDetails email_field_details { get; set construct; }

private Gtk.Grid grid;
private Gtk.Label email_address_label;
private Gtk.Entry email_address_entry;

public EmailGroupRow (Folks.EmailFieldDetails email_field_details) {
Object (
email_field_details: email_field_details
);
}

construct {
var label = new Gtk.Label ("unnamed");

email_address_label = new Gtk.Label (email_field_details.value);

grid = new Gtk.Grid ();
grid.attach (label, 0, 0);
grid.attach (email_address_label, 1, 0);
child = grid;

email_address_entry = new Gtk.Entry ();

email_address_label.bind_property ("label", email_address_entry, "text", BIDIRECTIONAL | SYNC_CREATE);
}

public void start_edit () {
grid.remove (email_address_label);
grid.attach (email_address_entry, 1, 0);
}

public void finish_edit (bool save) {
if (save) {
email_field_details = new Folks.EmailFieldDetails (email_address_entry.text);
}

grid.remove (email_address_entry);
grid.attach (email_address_label, 1, 0);
}
}
51 changes: 51 additions & 0 deletions src/Widgets/NameGroup.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
public class NameGroup : Gtk.Grid {
public Folks.NameDetails name_details { get; set; }

private Gtk.Label full_name_label;
private Gtk.Entry full_name_entry;

construct {
var header_label = new Granite.HeaderLabel (_("Name"));

var description_label = new Gtk.Label (_("Full Name: ")) {
xalign = 1
};

full_name_label = new Gtk.Label ("") {
ellipsize = Pango.EllipsizeMode.MIDDLE
};

full_name_entry = new Gtk.Entry ();

hexpand = true;
halign = CENTER;
attach (header_label, 0, 0, 2, 1);
attach (description_label, 0, 1);
attach (full_name_label, 1, 1);

full_name_label.bind_property ("label", full_name_entry, "text", BIDIRECTIONAL);

notify["name-details"].connect (() => {
full_name_label.label = name_details.full_name;
});
}

public void start_edit () {
remove (full_name_label);
attach (full_name_entry, 1, 1);
}

public async void finish_edit (bool save) {
if (save) {
try {
yield name_details.change_full_name (full_name_entry.text);
} catch (Error e) {
warning ("Failed to update full name: %s", e.message);
}
}

full_name_label.label = name_details.full_name;
remove (full_name_entry);
attach (full_name_label, 1, 1);
}
}