Commit 51744ffa authored by Julian Sparber's avatar Julian Sparber

Refactor link/unlink operations

This cleans up how linking and unlinking is done, by using the methodes
provided by folks.
parent 02412733
......@@ -259,7 +259,7 @@ public class Contacts.ContactEditor : ContactForm {
HashMap<int, RowData?> rows;
}
private ArrayList<Persona> unlink_personas;
private HashSet<Persona> unlink_personas;
/* the key of the hash_map is the uid of the persona */
private HashMap<string, HashMap<string, Field?>> writable_personas;
......@@ -276,7 +276,7 @@ public class Contacts.ContactEditor : ContactForm {
}
construct {
this.unlink_personas = new ArrayList<Persona> ();
this.unlink_personas = new HashSet<Persona> ();
this.writable_personas = new HashMap<string, HashMap<string, Field?>> ();
this.container_grid.size_allocate.connect(on_container_grid_size_allocate);
......@@ -1020,7 +1020,7 @@ public class Contacts.ContactEditor : ContactForm {
return props_set;
}
public ArrayList<Persona> get_unlink_personas () {
public HashSet<Persona> get_unlink_personas () {
return unlink_personas;
}
......
......@@ -70,6 +70,7 @@ public class Contacts.ContactList : ListBox {
}
private void on_contact_changed (Object obj, ParamSpec pspec) {
//TODO: Update also the Avatar
this.label.set_text (this.individual.display_name);
changed ();
}
......@@ -203,8 +204,8 @@ public class Contacts.ContactList : ListBox {
}
private void contact_added_cb (Store store, Individual i) {
// Don't create a row for ignorable contacts
if (!ContactUtils.is_ignorable (i)) {
// Don't create a row for ignorable contacts are the individual already has a row
if (!ContactUtils.is_ignorable (i) && find_row_for_contact(i) == null) {
var row = new ContactDataRow (i);
row.selector_button.toggled.connect ( () => { on_row_checkbox_toggled (row); });
row.selector_button.visible = (this.state == UiState.SELECTING);
......
......@@ -107,10 +107,12 @@ public class Contacts.ContactPane : Stack {
this.suggestion_grid.suggestion_accepted.connect ( () => {
var linked_contact = this.individual.display_name;
link_contacts.begin (this.individual, i, this.store, (obj, result) => {
var operation = link_contacts.end (result);
this.contacts_linked (null, linked_contact, operation);
});
var operation = new LinkOperation (this.store);
var to_link = new LinkedList<Individual> ();
to_link.add (this.individual);
to_link.add (i);
operation.do.begin (to_link);
this.contacts_linked (null, linked_contact, operation);
remove_suggestion_grid ();
});
......@@ -252,15 +254,6 @@ public class Contacts.ContactPane : Stack {
}
}
/* unlink personas */
/*
foreach (var persona in this.editor.get_unlink_personas()) {
unlink_persona.begin (store, contact, persona, (obj, result) => {
unlink_persona.end (result);
});
}
*/
if (this.editor.name_changed ()) {
var v = this.editor.get_full_name_value ();
try {
......@@ -279,6 +272,12 @@ public class Contacts.ContactPane : Stack {
show_message (e.message);
}
}
/* unlink personas */
if (this.editor.get_unlink_personas ().size > 0) {
var operation = new UnLinkOperation (this.store);
operation.do.begin (this.individual, this.editor.get_unlink_personas ());
}
}
public void new_contact () {
......
This diff is collapsed.
......@@ -42,19 +42,6 @@ public class Contacts.Store : GLib.Object {
get { return this.aggregator.is_prepared; }
}
private bool individual_can_replace_at_split (Individual new_individual) {
foreach (var p in new_individual.personas) {
if (p.get_data<bool> ("contacts-new-contact"))
return false;
}
return true;
}
private bool individual_should_replace_at_join (Individual old_individual) {
var c = old_individual;
return c.get_data<bool> ("contacts-master-at-join");
}
private void read_dont_suggest_db () {
dont_suggest_link.clear ();
try {
......@@ -153,73 +140,25 @@ public class Contacts.Store : GLib.Object {
}
private void on_individuals_changed_detailed (MultiMap<Individual?,Individual?> changes) {
// Note: Apparently the current implementation doesn't necessarily pick
// up unlinked individual as replacements.
var replaced_individuals = new HashMap<Individual?, Individual?> ();
var old_individuals = changes.get_keys();
debug ("Individuals changed: %d old, %d new", old_individuals.size - 1, changes[null].size);
// Pick best replacements at joins
foreach (var old_individual in old_individuals) {
if (old_individual == null)
continue;
foreach (var new_individual in changes[old_individual]) {
if (new_individual == null)
continue;
if (!replaced_individuals.has_key (new_individual)
|| individual_should_replace_at_join (old_individual)) {
replaced_individuals[new_individual] = old_individual;
}
var to_add = new HashSet<Individual> ();
var to_remove = new HashSet<Individual> ();
foreach (var i in changes.get_keys()) {
if (i != null)
to_remove.add (i);
foreach (var new_i in changes[i]) {
to_add.add (new_i);
}
}
foreach (var old_individual in old_individuals) {
HashSet<Individual>? replacements = null;
foreach (var new_individual in changes[old_individual]) {
if (old_individual != null && new_individual != null &&
replaced_individuals[new_individual] == old_individual) {
if (replacements == null)
replacements = new HashSet<Individual> ();
replacements.add (new_individual);
} else if (old_individual != null) {
// Removing an old individual.
removed (old_individual);
} else if (new_individual != null) {
// Adding a new individual.
added (new_individual);
}
}
// This old_individual was split up into one or more new ones
// We have to pick one to be the one that we keep around
// in the old Contact, the rest gets new Contacts
// This is important to get right, as we might be displaying
// the contact and unlink a specific persona from the contact
if (replacements != null) {
Individual? main_individual = null;
foreach (var i in replacements) {
main_individual = i;
// If this was marked as being possible to replace the
// contact on split then we can otherwise bail immediately
// Otherwise need to look for other possible better
// replacements that we should reuse
if (individual_can_replace_at_split (i))
break;
}
// Add new individuals
foreach (var i in to_add) {
if (i.personas.size > 0)
added (i);
}
/* Not sure
var c = Contact.from_individual (old_individual);
c.replace_individual (main_individual);
*/
foreach (var i in replacements) {
if (i != main_individual) {
// Already replaced this old_individual, i.e. we're splitting
// old_individual. We just make this a new one.
added (i);
}
}
}
// Remove old individuals
foreach (var i in to_remove) {
removed (i);
}
}
......
......@@ -164,6 +164,18 @@ namespace Contacts.Utils {
return stores;
}
public PersonaStore? get_key_file_address_book (Store contacts_store) {
foreach (var backend in contacts_store.backend_store.enabled_backends.values) {
foreach (var persona_store in backend.persona_stores.values) {
if (persona_store.type_id == "key-file") {
return persona_store;
}
}
}
return null;
}
public void show_error_dialog (string error, Gtk.Window toplevel) {
var dialog = new Gtk.MessageDialog (toplevel,
Gtk.DialogFlags.MODAL,
......
......@@ -411,18 +411,16 @@ public class Contacts.Window : Gtk.ApplicationWindow {
set_shown_contact (null);
this.state = UiState.NORMAL;
LinkOperation2 operation = null;
link_contacts_list.begin (contact_list, this.store, (obj, result) => {
operation = link_contacts_list.end (result);
});
var operation = new LinkOperation (this.store);
operation.do.begin (contact_list);
string msg = ngettext ("%d contacts linked",
"%d contacts linked",
contact_list.size).printf (contact_list.size);
var b = new Button.with_mnemonic (_("_Undo"));
var notification = new InAppNotification (msg, b);
var notification = new InAppNotification (msg);
/* signal handlers */
b.clicked.connect ( () => {
/* here, we will unlink the thing in question */
......
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