3
* Ekiga -- A VoIP and Video-Conferencing application
4
* Copyright (C) 2000-2007 Damien Sandras
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or (at
9
* your option) any later version. This program is distributed in the hope
10
* that it will be useful, but WITHOUT ANY WARRANTY; without even the
11
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
* See the GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License along
15
* with this program; if not, write to the Free Software Foundation, Inc.,
16
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
18
* Ekiga is licensed under the GPL license and as a special exception, you
19
* have permission to link or otherwise combine this program with the
20
* programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
21
* applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
22
* programs, as long as you do follow the requirements of the GNU GPL for all
23
* the rest of the software thus combined.
28
* local-heap.cpp - description
29
* ------------------------------------------
30
* begin : written in 2007 by Julien Puydt
31
* copyright : (c) 2007 by Julien Puydt
32
* description : implementation of the heap of the local roster
42
#include "form-request-simple.h"
44
#include "local-heap.h"
46
#define KEY "/apps/" PACKAGE_NAME "/contacts/roster"
52
Local::Heap::Heap (Ekiga::ServiceCore &_core): core (_core), doc (NULL)
56
presence_core = dynamic_cast<Ekiga::PresenceCore*>(core.get ("presence-core"));
58
gchar *c_raw = gm_conf_get_string (KEY);
60
// Build the XML document representing the contacts list from the configuration
63
const std::string raw = c_raw;
64
doc = xmlRecoverMemory (raw.c_str (), raw.length ());
66
root = xmlDocGetRootElement (doc);
69
root = xmlNewDocNode (doc, NULL, BAD_CAST "list", NULL);
70
xmlDocSetRootElement (doc, root);
73
for (xmlNodePtr child = root->children; child != NULL; child = child->next)
74
if (child->type == XML_ELEMENT_NODE
75
&& child->name != NULL
76
&& xmlStrEqual (BAD_CAST ("entry"), child->name))
81
// Or create a new XML document
85
doc = xmlNewDoc (BAD_CAST "1.0");
86
root = xmlNewDocNode (doc, NULL, BAD_CAST "list", NULL);
87
xmlDocSetRootElement (doc, root);
90
// add 500 and 501 at ekiga.net in this case!
91
std::set<std::string> groups;
93
groups.insert (_("Services"));
94
add (_("Echo test"), "sip:500@ekiga.net", groups);
95
add (_("Conference room"), "sip:501@ekiga.net", groups);
101
Local::Heap::~Heap ()
109
Local::Heap::get_name () const
111
return _("Local roster");
116
Local::Heap::populate_menu (Ekiga::MenuBuilder &builder)
118
builder.add_action ("new", _("New contact"),
119
sigc::bind (sigc::mem_fun (this, &Local::Heap::new_presentity), "", ""));
125
Local::Heap::populate_menu_for_group (const std::string name,
126
Ekiga::MenuBuilder& builder)
128
builder.add_action ("rename_group", _("Rename"),
129
sigc::bind (sigc::mem_fun (this, &Local::Heap::on_rename_group), name));
135
Local::Heap::has_presentity_with_uri (const std::string uri) const
139
for (const_iterator iter = begin ();
140
iter != end () && result != true;
142
result = (iter->get_uri () == uri);
148
const std::set<std::string>
149
Local::Heap::existing_groups () const
151
std::set<std::string> result;
153
for (const_iterator iter = begin ();
157
std::set<std::string> groups = iter->get_groups ();
158
result.insert (groups.begin (), groups.end ());
166
Local::Heap::new_presentity (const std::string name,
167
const std::string uri)
169
if (!has_presentity_with_uri (uri)) {
171
Ekiga::FormRequestSimple request;
172
std::set<std::string> groups = existing_groups ();
174
request.title (_("Add to local roster"));
175
request.instructions (_("Please fill in this form to add a new contact "
176
"to ekiga's internal roster"));
177
request.text ("name", _("Name:"), name);
178
if (presence_core->is_supported_uri (uri)) {
180
request.hidden ("good-uri", "yes");
181
request.hidden ("uri", uri);
184
request.hidden ("good-uri", "no");
186
request.text ("uri", _("Address:"), uri);
188
request.text ("uri", _("Address:"), "sip:"); // let's put a default
191
request.editable_set ("groups",
192
_("Put contact in groups:"),
193
std::set<std::string>(), groups);
195
request.submitted.connect (sigc::mem_fun (this, &Local::Heap::new_presentity_form_submitted));
197
if (!questions.handle_request (&request)) {
199
// FIXME: better error reporting
201
std::cout << "Unhandled form request in "
202
<< __PRETTY_FUNCTION__ << std::endl;
213
Local::Heap::add (xmlNodePtr node)
215
Presentity *presentity = NULL;
217
presentity = new Presentity (core, node);
219
common_add (*presentity);
224
Local::Heap::add (const std::string name,
225
const std::string uri,
226
const std::set<std::string> groups)
228
Presentity *presentity = NULL;
229
xmlNodePtr root = NULL;
231
root = xmlDocGetRootElement (doc);
232
presentity = new Presentity (core, name, uri, groups);
234
xmlAddChild (root, presentity->get_node ());
237
common_add (*presentity);
242
Local::Heap::common_add (Presentity &presentity)
244
// Add the presentity to this Heap
245
add_presentity (presentity);
248
presence_core->fetch_presence (presentity.get_uri ());
250
// Connect the Local::Presentity signals.
251
presentity.trigger_saving.connect (sigc::mem_fun (this, &Local::Heap::save));
256
Local::Heap::save () const
258
xmlChar *buffer = NULL;
261
xmlDocDumpMemory (doc, &buffer, &size);
263
gm_conf_set_string (KEY, (const char *)buffer);
270
Local::Heap::new_presentity_form_submitted (Ekiga::Form &result)
274
const std::string name = result.text ("name");
275
const std::string good_uri = result.hidden ("good-uri");
277
const std::set<std::string> groups = result.editable_set ("groups");
279
if (good_uri == "yes")
280
uri = result.hidden ("uri");
282
uri = result.text ("uri");
284
if (presence_core->is_supported_uri (uri)
285
&& !has_presentity_with_uri (uri)) {
287
add (name, uri, groups);
291
Ekiga::FormRequestSimple request;
293
result.visit (request);
294
if (!presence_core->is_supported_uri (uri))
295
request.error (_("You supplied an unsupported address"));
297
request.error (_("You already have a contact with this address!"));
298
request.submitted.connect (sigc::mem_fun (this, &Local::Heap::new_presentity_form_submitted));
299
if (!questions.handle_request (&request)) {
301
// FIXME: better error handling
303
std::cout << "Unhandled form request in "
304
<< __PRETTY_FUNCTION__ << std::endl;
308
} catch (Ekiga::Form::not_found) {
311
std::cerr << "Invalid form submitted to "
312
<< __PRETTY_FUNCTION__ << std::endl;
318
Local::Heap::on_rename_group (std::string name)
320
Ekiga::FormRequestSimple request;
322
request.title (_("Rename group"));
323
request.instructions (_("Please edit this group name"));
324
request.text ("name", _("Name:"), name);
326
request.submitted.connect (sigc::bind<0>(sigc::mem_fun (this, &Local::Heap::rename_group_form_submitted), name));
328
if (!questions.handle_request (&request)) {
330
// FIXME: better error reporting
332
std::cout << "Unhandled form request in "
333
<< __PRETTY_FUNCTION__ << std::endl;
339
Local::Heap::rename_group_form_submitted (std::string old_name,
343
const std::string new_name = result.text ("name");
345
if ( !new_name.empty () && new_name != old_name) {
347
for (iterator iter = begin ();
351
iter->rename_group (old_name, new_name);
354
} catch (Ekiga::Form::not_found) {
357
std::cerr << "Invalid form submitted to "
358
<< __PRETTY_FUNCTION__ << std::endl;