summaryrefslogtreecommitdiff
path: root/src/core/contacts-im-addresses-chunk.vala
blob: 4d3effb30ef1807d4cac588ca6ef75500e5dee83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 * Copyright (C) 2022 Niels De Graef <nielsdegraef@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

using Folks;

/**
 * A {@link Chunk} that represents the internet messaging (IM) addresses of a
 * contact (similar to {@link Folks.ImDetails}}. Each element is a
 * {@link ImAddress}.
 */
public class Contacts.ImAddressesChunk : BinChunk {

  public override string property_name { get { return "im-addresses"; } }

  construct {
    if (persona != null) {
      return_if_fail (persona is ImDetails);
      unowned var im_details = (ImDetails) persona;

      var iter = im_details.im_addresses.map_iterator ();
      while (iter.next ()) {
        var protocol = iter.get_key ();
        var im = new ImAddress.from_field_details (iter.get_value (), protocol);
        add_child (im);
      }
    }

    finish_initialization ();
  }

  protected override BinChunkChild create_empty_child () {
    return new ImAddress ();
  }

  public override async void save_to_persona () throws GLib.Error
      requires (this.persona is ImDetails) {
    // We can't use get_abstract_field_details() here, since we need the
    // protocol as well, and to use a Gee.MultiMap for it
    var afds = new Gee.HashMultiMap<string, ImFieldDetails> ();
    for (uint i = 0; i < get_n_items (); i++) {
      var im_addr = (ImAddress) get_item (i);
      var afd = (ImFieldDetails) im_addr.create_afd ();
      if (afd != null)
        afds[im_addr.protocol] = afd;
    }

    yield ((ImDetails) this.persona).change_im_addresses (afds);
  }
}

public class Contacts.ImAddress : BinChunkChild {

  public string protocol { get; private set; default = ""; }

  public string address {
    get { return this._address; }
    set { change_string_prop ("address", ref this._address, value); }
  }
  private string _address = "";

  public override bool is_empty {
    get { return this.address.strip () == ""; }
  }

  public override string icon_name {
    get { return "chat-symbolic"; }
  }

  public ImAddress () {
    this.parameters = new Gee.HashMultiMap<string, string> ();
  }

  public ImAddress.from_field_details (ImFieldDetails im_field, string protocol) {
    this.address = im_field.value;
    this.protocol = protocol;
    this.parameters = im_field.parameters;
  }

  protected override int compare_internal (BinChunkChild other)
      requires (other is ImAddress) {
    unowned var other_im_addr = (ImAddress) other;

    var protocol_cmp = strcmp (this.protocol, other_im_addr.protocol);
    if (protocol_cmp != 0)
      return protocol_cmp;

    var addr_cmp = strcmp (this.address, other_im_addr.address);
    if (addr_cmp != 0)
      return addr_cmp;

    return dummy_compare_parameters (other);
  }

  public override AbstractFieldDetails? create_afd () {
    if (this.is_empty)
      return null;

    return new ImFieldDetails (this.address, this.parameters);
  }

  public override BinChunkChild copy () {
    var ima = new ImAddress ();
    ima.protocol = this.protocol;
    ima.address = this.address;
    copy_parameters (ima);
    return ima;
  }

  protected override Variant? to_gvariant_internal () {
    return new Variant ("(ssv)",
                        this.protocol,
                        this.address,
                        parameters_to_gvariant ());
  }

  public override void apply_gvariant (Variant variant)
      requires (variant.get_type ().equal (new VariantType ("(ssv)"))) {

    string protocol, address;
    Variant params_variant;
    variant.get ("(ssv)", out protocol, out address, out params_variant);

    this.protocol = protocol;
    this.address = address;
    apply_gvariant_parameters (params_variant);
  }
}