DefaultLogic is now using an accounts list for accounts and contacts management. Fixed account and contact add/edit bugs. Calls log is now shown using a common table for incoming and outgoing. Fixed DefaultLogic resource.notify and user.roster processing.

git-svn-id: http://voip.null.ro/svn/yate@3308 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2010-05-11 14:25:41 +00:00
parent d8c19b1f84
commit 26eb5b1917
6 changed files with 1813 additions and 1205 deletions

View File

@ -2230,7 +2230,11 @@ bool Client::buildIncomingChannel(Message& msg, const String& dest)
// Build an outgoing channel
bool Client::buildOutgoingChannel(NamedList& params)
{
Debug(ClientDriver::self(),DebugAll,"Client::buildOutgoingChannel() [%p]",this);
String tmp;
//#ifdef DEBUG
params.dump(tmp," ");
//#endif
Debug(ClientDriver::self(),DebugAll,"Client::buildOutgoingChannel(%s) [%p]",tmp.safe(),this);
// get the target of the call
NamedString* target = params.getParam("target");
if (TelEngine::null(target))
@ -3385,35 +3389,40 @@ ClientChannel* ClientDriver::findChanByPeer(const String& peer)
* ClientAccount
*/
// Constructor
ClientAccount::ClientAccount(const char* proto, const char* user,
const char* host, bool startup)
ClientAccount::ClientAccount(const char* proto, const char* user, const char* host,
bool startup, ClientContact* contact)
: Mutex(true,"ClientAccount"),
m_port(0), m_startup(startup), m_expires(-1), m_connected(false),
m_resource(0)
m_params(""), m_resource(0), m_contact(0)
{
setIdUri(proto,user,host);
setResource(new ClientResource(""));
DDebug(ClientDriver::self(),DebugAll,"Created client account=%s [%p]",
m_uri.c_str(),this);
m_params.addParam("enabled",String::boolText(startup));
m_params.addParam("protocol",proto,false);
m_params.addParam("username",user,false);
m_params.addParam("domain",host,false);
setResource(new ClientResource(m_params.getValue("resource")));
setContact(contact);
Debug(ClientDriver::self(),DebugAll,"Created client account='%s' [%p]",
toString().c_str(),this);
}
// Constructor. Build an account from a list of parameters.
ClientAccount::ClientAccount(const NamedList& params)
ClientAccount::ClientAccount(const NamedList& params, ClientContact* contact)
: Mutex(true,"ClientAccount"),
m_port(0), m_startup(false), m_expires(-1), m_connected(false),
m_resource(0)
m_params(params), m_resource(0), m_contact(0)
{
setIdUri(params.getValue("protocol"),params.getValue("username"),params.getValue("domain"));
m_startup = params.getBoolValue("enable");
m_password = params.getValue("password");
setResource(new ClientResource(params.getValue("resource")));
m_server = params.getValue("server");
m_options = params.getValue("options");
m_port = params.getIntValue("port",m_port);
m_outbound = params.getValue("outbound");
m_expires = params.getIntValue("expires",m_expires);
DDebug(ClientDriver::self(),DebugAll,"Created client account=%s [%p]",
m_uri.c_str(),this);
setResource(new ClientResource(m_params.getValue("resource")));
setContact(contact);
Debug(ClientDriver::self(),DebugAll,"Created client account='%s' [%p]",
toString().c_str(),this);
}
// Set account own contact
void ClientAccount::setContact(ClientContact* contact)
{
Lock lock(this);
if (m_contact == contact)
return;
TelEngine::destruct(m_contact);
m_contact = contact;
}
// Get this account's resource
@ -3437,19 +3446,64 @@ void ClientAccount::setResource(ClientResource* res)
m_resource = res;
}
// Save this account to client accounts file
bool ClientAccount::save(bool ok, bool savePwd)
{
NamedList* sect = Client::s_accounts.getSection(toString());
if (ok) {
if (!sect)
sect = Client::s_accounts.createSection(toString());
if (!sect)
return false;
*sect = m_params;
if (!savePwd)
sect->clearParam("password");
sect->assign(toString());
}
else if (sect)
Client::s_accounts.clearSection(toString());
else
return true;
return Client::save(Client::s_accounts);
}
// Find a contact by its id
ClientContact* ClientAccount::findContact(const String& id, bool ref)
{
Lock lock(this);
ObjList* obj = m_contacts.find(id);
if (!obj)
if (!id)
return 0;
ClientContact* c = static_cast<ClientContact*>(obj->get());
return (!ref || c->ref()) ? c : 0;
Lock lock(this);
ClientContact* c = 0;
if (!m_contact || id != m_contact->toString()) {
ObjList* o = m_contacts.skipNull();
while (o && o->get()->toString() != id)
o = o->skipNext();
c = o ? static_cast<ClientContact*>(o->get()) : 0;
}
else
c = m_contact;
return c && (!ref || c->ref()) ? c : 0;
}
// Find a contact by name and/or uri
ClientContact* ClientAccount::findContact(const String* name, const String* uri,
const String* skipId, bool ref)
{
if (!(name || uri))
return 0;
Lock lock(this);
for (ObjList* o = m_contacts.skipNull(); o; o = o->skipNext()) {
ClientContact* c = static_cast<ClientContact*>(o->get());
if ((skipId && *skipId == c->toString()) ||
(name && *name != c->m_name) || (uri && *uri != c->uri()))
continue;
return (!ref || c->ref()) ? c : 0;
}
return 0;
}
// Find a contact having a given id and resource
ClientContact* ClientAccount::findContact(const String& id, const String& resid,
ClientContact* ClientAccount::findContact(const String& id, const String& resid,
bool ref)
{
Lock lock(this);
@ -3459,6 +3513,15 @@ ClientContact* ClientAccount::findContact(const String& id, const String& resid,
return (!ref || c->ref()) ? c : 0;
}
// Find a contact by its URI (build an id from account and uri)
ClientContact* ClientAccount::findContactByUri(const String& uri, bool ref)
{
Lock lock(this);
String id;
ClientContact::buildContactId(id,toString(),uri);
return findContact(id,ref);
}
// Build a contact and append it to the list
ClientContact* ClientAccount::appendContact(const String& id, const char* name)
{
@ -3484,14 +3547,15 @@ ClientContact* ClientAccount::removeContact(const String& id, bool delObj)
{
Lock lock(this);
ClientContact* c = findContact(id);
if (!c)
if (!c || c == m_contact)
return 0;
m_contacts.remove(c,false);
c->m_owner = 0;
lock.drop();
Debug(ClientDriver::self(),DebugAll,
"Account(%s) removed contact '%s' delObj=%u [%p]",
m_uri.c_str(),c->uri().c_str(),delObj,this);
"Account(%s) removed contact '%s' name='%s' uri='%s' delObj=%u [%p]",
toString().c_str(),c->toString().c_str(),c->m_name.c_str(),c->uri().c_str(),
delObj,this);
if (delObj)
TelEngine::destruct(c);
return c;
@ -3500,44 +3564,38 @@ ClientContact* ClientAccount::removeContact(const String& id, bool delObj)
// Build a login/logout message from account's data
Message* ClientAccount::userlogin(bool login, const char* msg)
{
#define SAFE_FILL(param,value) { if(value) m->addParam(param,value); }
Message* m = new Message(msg);
m->addParam("account",m_id);
m->addParam("operation",login ? "create" : "delete");
// Fill login data
if (login) {
SAFE_FILL("username",m_uri.getUser());
SAFE_FILL("password",m_password);
SAFE_FILL("domain",m_uri.getHost());
lock();
if (m_resource)
SAFE_FILL("resource",m_resource->toString());
unlock();
SAFE_FILL("server",m_server);
SAFE_FILL("options",m_options);
if (m_port)
m->addParam("port",String(m_port));
SAFE_FILL("outbound",m_outbound);
if (m_expires >= 0)
m->addParam("expires",String(m_expires));
}
SAFE_FILL("protocol",m_id.getProtocol());
#undef SAFE_FILL
Message* m = Client::buildMessage(msg,toString(),login ? "login" : "logout");
if (login)
m->copyParams(m_params);
else
m->addParam("protocol",protocol(),false);
return m;
}
// Fill a list used to update an account list item
void ClientAccount::fillItemParams(NamedList& list)
{
list.addParam("account",toString());
list.addParam("protocol",m_params.getValue("protocol"));
const char* sName = resource().statusName();
NamedString* status = new NamedString("status",sName);
status->append(resource().m_text,": ");
list.addParam(status);
}
// Remove from owner. Release data
void ClientAccount::destroyed()
{
lock();
TelEngine::destruct(m_resource);
TelEngine::destruct(m_contact);
// Clear contacts. Remove their owner before
for (ObjList* o = m_contacts.skipNull(); o; o = o->skipNext())
(static_cast<ClientContact*>(o->get()))->m_owner = 0;
m_contacts.clear();
unlock();
DDebug(ClientDriver::self(),DebugAll,"Destroyed client account=%s [%p]",
m_uri.c_str(),this);
Debug(ClientDriver::self(),DebugAll,"Destroyed client account=%s [%p]",
toString().c_str(),this);
RefObject::destroyed();
}
@ -3550,8 +3608,9 @@ void ClientAccount::appendContact(ClientContact* contact)
m_contacts.append(contact);
contact->m_owner = this;
Debug(ClientDriver::self(),DebugAll,
"Account(%s) added contact '%s' [%p]",
m_uri.c_str(),contact->uri().c_str(),this);
"Account(%s) added contact '%s' name='%s' uri='%s' [%p]",
toString().c_str(),contact->toString().c_str(),contact->m_name.c_str(),
contact->uri().c_str(),this);
}
@ -3576,15 +3635,28 @@ ClientAccount* ClientAccountList::findAccount(const String& id, bool ref)
Lock lock(this);
if (m_localContacts && m_localContacts->toString() == id)
return (!ref || m_localContacts->ref()) ? m_localContacts : 0;
ObjList* obj = m_accounts.find(id);
if (!obj)
if (!id)
return 0;
ClientAccount* a = static_cast<ClientAccount*>(obj->get());
return (!ref || a->ref()) ? a : 0;
for (ObjList* o = m_accounts.skipNull(); o; o = o->skipNext()) {
ClientAccount* a = static_cast<ClientAccount*>(o->get());
if (a->toString() == id)
return (!ref || a->ref()) ? a : 0;
}
return 0;
}
// Find an account's contact by its URI
ClientContact* ClientAccountList::findContactByUri(const String& account, const String& uri,
bool ref)
{
Lock lock(this);
ClientAccount* acc = findAccount(account,false);
return acc ? acc->findContactByUri(uri,ref) : 0;
}
// Find an account's contact
ClientContact* ClientAccountList::findContact(const String& account, const String& id, bool ref)
ClientContact* ClientAccountList::findContact(const String& account, const String& id,
bool ref)
{
Lock lock(this);
ClientAccount* acc = findAccount(account,false);
@ -3594,11 +3666,39 @@ ClientContact* ClientAccountList::findContact(const String& account, const Strin
// Find an account's contact from a built id
ClientContact* ClientAccountList::findContact(const String& builtId, bool ref)
{
String account, contact;
ClientContact::splitContactId(builtId,account,contact);
String account;
ClientContact::splitContactId(builtId,account);
return findContact(account,builtId,ref);
}
// Find a contact an instance id
ClientContact* ClientAccountList::findContactByInstance(const String& id, String* instance,
bool ref)
{
String account,contact;
ClientContact::splitContactInstanceId(id,account,contact,instance);
return findContact(account,contact,ref);
}
// Check if there is a single registered account and return it
ClientAccount* ClientAccountList::findSingleRegAccount(const String* skipProto, bool ref)
{
Lock lock(this);
ClientAccount* found = 0;
for (ObjList* o = m_accounts.skipNull(); o; o = o->skipNext()) {
ClientAccount* a = static_cast<ClientAccount*>(o->get());
if (!a->resource().online() || (skipProto && *skipProto == a->protocol()))
continue;
if (!found)
found = a;
else {
found = 0;
break;
}
}
return (found && (!ref || found->ref())) ? found : 0;
}
// Append a new account
bool ClientAccountList::appendAccount(ClientAccount* account)
{
@ -3606,7 +3706,7 @@ bool ClientAccountList::appendAccount(ClientAccount* account)
return false;
m_accounts.append(account);
DDebug(ClientDriver::self(),DebugAll,"List(%s) added account '%s'",
c_str(),account->uri().c_str());
c_str(),account->toString().c_str());
return true;
}
@ -3618,7 +3718,7 @@ void ClientAccountList::removeAccount(const String& id)
if (!obj)
return;
DDebug(ClientDriver::self(),DebugAll,"List(%s) removed account '%s'",
c_str(),(static_cast<ClientAccount*>(obj->get()))->uri().c_str());
c_str(),obj->get()->toString().c_str());
obj->remove();
}
@ -3642,11 +3742,11 @@ ClientContact::ClientContact(ClientAccount* owner, const char* id, const char* n
}
// Constructor. Build a contact from a list of parameters.
ClientContact::ClientContact(ClientAccount* owner, NamedList& params, bool chat)
: m_name(params.getValue("name",params)), m_owner(owner), m_uri(params)
ClientContact::ClientContact(ClientAccount* owner, const NamedList& params, const char* id,
const char* uri, bool chat)
: m_name(params.getValue("name",params)), m_owner(owner), m_uri(uri)
{
m_id = m_uri;
m_id.toLower();
m_id = id ? id : params.c_str();
XDebug(ClientDriver::self(),DebugAll,"ClientContact(%p,%s) [%p]",
owner,m_uri.c_str(),this);
if (m_owner)
@ -3698,9 +3798,7 @@ void ClientContact::createChatWindow(bool force, const char* name)
Window* w = Client::self()->getWindow(m_chatWndName);
if (!w)
return;
String id;
buildContactId(id);
w->context(id);
w->context(toString());
NamedList tmp("");
tmp.addParam("contactname",m_name);
Client::self()->setParams(&tmp,w);
@ -3724,7 +3822,7 @@ bool ClientContact::appendGroup(const String& group)
m_groups.append(new String(group));
DDebug(ClientDriver::self(),DebugAll,
"Account(%s) contact='%s' added group '%s' [%p]",
m_owner ? m_owner->uri().c_str() : "",m_uri.c_str(),group.c_str(),this);
m_owner ? m_owner->toString().c_str() : "",m_uri.c_str(),group.c_str(),this);
return true;
}
@ -3738,7 +3836,7 @@ bool ClientContact::removeGroup(const String& group)
obj->remove();
DDebug(ClientDriver::self(),DebugAll,
"Account(%s) contact='%s' removed group '%s' [%p]",
m_owner ? m_owner->uri().c_str() : "",m_uri.c_str(),group.c_str(),this);
m_owner ? m_owner->toString().c_str() : "",m_uri.c_str(),group.c_str(),this);
return true;
}
@ -3816,10 +3914,30 @@ bool ClientContact::removeResource(const String& id)
obj->remove();
DDebug(ClientDriver::self(),DebugAll,
"Account(%s) contact='%s' removed resource '%s' [%p]",
m_owner ? m_owner->uri().c_str() : "",m_uri.c_str(),id.c_str(),this);
m_owner ? m_owner->toString().c_str() : "",m_uri.c_str(),id.c_str(),this);
return true;
}
// Split a contact instance id in account/contact/instance parts
void ClientContact::splitContactInstanceId(const String& src, String& account,
String& contact, String* instance)
{
int pos = src.find('|');
if (pos < 0) {
account = src.uriUnescape();
return;
}
account = src.substr(0,pos).uriUnescape();
int pp = src.find('|',pos + 1);
if (pp > pos) {
contact = src.substr(0,pp);
if (instance)
*instance = src.substr(pp + 1).uriUnescape();
}
else
contact = src;
}
// Remove from owner. Release data
void ClientContact::destroyed()
{

File diff suppressed because it is too large Load Diff

View File

@ -12,8 +12,7 @@ new phone calls.
<p>
You can create new contacts by hand or by using
the <b>Contact</b> button in either Received or
Dialed log panel.
the <b>Contact</b> button in the log panel.
</p>
</markup><!-- pango -->

View File

@ -9,7 +9,7 @@
<x>0</x>
<y>0</y>
<width>500</width>
<height>285</height>
<height>280</height>
</rect>
</property>
<property name="sizePolicy" >
@ -21,13 +21,13 @@
<property name="minimumSize" >
<size>
<width>500</width>
<height>285</height>
<height>280</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>500</width>
<height>285</height>
<height>280</height>
</size>
</property>
<property name="windowTitle" >
@ -41,16 +41,16 @@
<number>2</number>
</property>
<property name="leftMargin" >
<number>9</number>
<number>6</number>
</property>
<property name="topMargin" >
<number>9</number>
<number>6</number>
</property>
<property name="rightMargin" >
<number>9</number>
<number>6</number>
</property>
<property name="bottomMargin" >
<number>9</number>
<number>4</number>
</property>
<item>
<layout class="QHBoxLayout" >
@ -71,15 +71,21 @@
</property>
<item>
<widget class="QFrame" name="frame_protocol" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>210</width>
<width>220</width>
<height>16</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>210</width>
<width>220</width>
<height>16777215</height>
</size>
</property>
@ -108,7 +114,7 @@
<item>
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>6</number>
<number>2</number>
</property>
<property name="leftMargin" >
<number>0</number>
@ -124,6 +130,24 @@
</property>
<item>
<widget class="QLabel" name="label_protocol" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>66</width>
<height>0</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>66</width>
<height>16777215</height>
</size>
</property>
<property name="text" >
<string>Protocol:</string>
</property>
@ -132,14 +156,14 @@
<item>
<widget class="QComboBox" name="acc_protocol" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>120</width>
<width>0</width>
<height>25</height>
</size>
</property>
@ -159,7 +183,7 @@
<item>
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>6</number>
<number>2</number>
</property>
<property name="leftMargin" >
<number>0</number>
@ -175,6 +199,24 @@
</property>
<item>
<widget class="QLabel" name="label" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text" >
<string>Use provider:</string>
</property>
@ -183,14 +225,14 @@
<item>
<widget class="QComboBox" name="acc_providers" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>120</width>
<width>0</width>
<height>25</height>
</size>
</property>
@ -251,16 +293,22 @@
</property>
<item>
<widget class="QFrame" name="frame_account" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>210</width>
<height>148</height>
<width>220</width>
<height>136</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>210</width>
<height>444</height>
<width>220</width>
<height>136</height>
</size>
</property>
<property name="frameShape" >
@ -304,6 +352,24 @@
</property>
<item>
<widget class="QLabel" name="label_3" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>66</width>
<height>0</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>66</width>
<height>16777215</height>
</size>
</property>
<property name="text" >
<string>Account:</string>
</property>
@ -312,14 +378,14 @@
<item>
<widget class="QLineEdit" name="acc_account" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>152</width>
<width>0</width>
<height>25</height>
</size>
</property>
@ -355,6 +421,24 @@
</property>
<item>
<widget class="QLabel" name="label_5" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>66</width>
<height>0</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>66</width>
<height>16777215</height>
</size>
</property>
<property name="text" >
<string>Username:</string>
</property>
@ -398,20 +482,20 @@
<item>
<widget class="QLineEdit" name="acc_domain" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>78</width>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>78</width>
<width>16777215</width>
<height>25</height>
</size>
</property>
@ -438,6 +522,24 @@
</property>
<item>
<widget class="QLabel" name="label_7" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>66</width>
<height>0</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>66</width>
<height>16777215</height>
</size>
</property>
<property name="text" >
<string>Password:</string>
</property>
@ -446,14 +548,14 @@
<item>
<widget class="QLineEdit" name="acc_password" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>152</width>
<width>0</width>
<height>25</height>
</size>
</property>
@ -489,6 +591,24 @@
</property>
<item>
<widget class="QLabel" name="label_4" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>66</width>
<height>0</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>66</width>
<height>16777215</height>
</size>
</property>
<property name="text" >
<string>Server:</string>
</property>
@ -497,14 +617,14 @@
<item>
<widget class="QLineEdit" name="acc_server" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>152</width>
<width>0</width>
<height>25</height>
</size>
</property>
@ -518,6 +638,19 @@
</item>
</layout>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="spacing" >
@ -549,7 +682,7 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="toggleAccAdvanced" >
<widget class="QPushButton" name="acc_showadvanced" >
<property name="minimumSize" >
<size>
<width>80</width>
@ -574,16 +707,22 @@
</item>
<item>
<widget class="QStackedWidget" name="acc_proto_spec" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>16</width>
<height>148</height>
<height>136</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>500</width>
<height>148</height>
<height>136</height>
</size>
</property>
<property name="frameShape" >
@ -615,7 +754,7 @@
<item>
<widget class="QLabel" name="label_2" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -629,6 +768,9 @@
<property name="pixmap" >
<pixmap>null_team-48.png</pixmap>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
@ -658,17 +800,8 @@
<height>0</height>
</size>
</property>
<property name="title" >
<string/>
</property>
<property name="alignment" >
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="flat" >
<bool>true</bool>
</property>
<property name="checkable" >
<bool>false</bool>
<property name="styleSheet" >
<string>border: 0px;</string>
</property>
<layout class="QVBoxLayout" >
<property name="spacing" >
@ -710,16 +843,6 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="acc_proto_jabber_opt_oldstyleauth" >
<property name="text" >
<string>Use old style authentication</string>
</property>
<property name="autoExclusive" >
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -1081,7 +1204,7 @@
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
<number>4</number>
</property>
<property name="rightMargin" >
<number>0</number>

View File

@ -397,7 +397,7 @@
<enum>QFrame::Raised</enum>
</property>
<property name="currentIndex" >
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="PageCalls" >
<property name="sizePolicy" >
@ -1628,465 +1628,249 @@
<number>9</number>
</property>
<item>
<widget class="QFrame" name="framePageCDR" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>4</number>
</property>
<property name="frameShape" >
<enum>QFrame::NoFrame</enum>
<property name="leftMargin" >
<number>0</number>
</property>
<property name="frameShadow" >
<enum>QFrame::Raised</enum>
<property name="topMargin" >
<number>0</number>
</property>
<property name="lineWidth" >
<number>1</number>
<property name="rightMargin" >
<number>0</number>
</property>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>4</number>
</property>
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="tabWidget" >
<property name="currentIndex" >
<number>0</number>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<widget class="QTableWidget" name="log" >
<property name="editTriggers" >
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode" >
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior" >
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="columnCount" >
<number>3</number>
</property>
<column>
<property name="text" >
<string>Party</string>
</property>
<widget class="QWidget" name="tabLogOutgoing" >
<attribute name="title" >
<string>Dialed</string>
</attribute>
<attribute name="icon" >
<iconset>up.png</iconset>
</attribute>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>4</number>
</property>
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>4</number>
</property>
<property name="leftMargin" >
<number>3</number>
</property>
<property name="topMargin" >
<number>3</number>
</property>
<property name="rightMargin" >
<number>3</number>
</property>
<property name="bottomMargin" >
<number>3</number>
</property>
<item>
<widget class="QTableWidget" name="log_outgoing" >
<property name="autoFillBackground" >
<bool>false</bool>
</property>
<property name="editTriggers" >
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors" >
<bool>true</bool>
</property>
<property name="selectionMode" >
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior" >
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="columnCount" >
<number>3</number>
</property>
<column>
<property name="text" >
<string>Caller</string>
</property>
</column>
<column>
<property name="text" >
<string>Called</string>
</property>
</column>
<column>
<property name="text" >
<string>Duration</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>0</number>
</property>
<property name="leftMargin" >
<number>3</number>
</property>
<property name="topMargin" >
<number>3</number>
</property>
<property name="rightMargin" >
<number>3</number>
</property>
<property name="bottomMargin" >
<number>3</number>
</property>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="log_out_call" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>64</width>
<height>25</height>
</size>
</property>
<property name="toolTip" >
<string>Call back this number</string>
</property>
<property name="text" >
<string>Call</string>
</property>
<property name="icon" >
<iconset>phone.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="log_out_clear" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>64</width>
<height>25</height>
</size>
</property>
<property name="toolTip" >
<string>Clear all incoming calls log</string>
</property>
<property name="text" >
<string>Clear</string>
</property>
<property name="icon" >
<iconset>cdr_clear.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
<property name="_yate_identity" stdset="0" >
<string>clear:log_outgoing</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="log_out_contact" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>64</width>
<height>25</height>
</size>
</property>
<property name="toolTip" >
<string>Turn this number into a contact</string>
</property>
<property name="text" >
<string>Contact</string>
</property>
<property name="icon" >
<iconset>book.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</column>
<column>
<property name="text" >
<string>Time</string>
</property>
</column>
<column>
<property name="text" >
<string>Duration</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>2</number>
</property>
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>4</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="log_call" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>70</width>
<height>25</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>70</width>
<height>25</height>
</size>
</property>
<property name="toolTip" >
<string>Call back this number</string>
</property>
<property name="text" >
<string>Call</string>
</property>
<property name="icon" >
<iconset>phone.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</widget>
<widget class="QWidget" name="tabLogIncoming" >
<attribute name="title" >
<string>Received</string>
</attribute>
<attribute name="icon" >
<iconset>down.png</iconset>
</attribute>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>0</number>
</property>
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>4</number>
</property>
<property name="leftMargin" >
<number>3</number>
</property>
<property name="topMargin" >
<number>3</number>
</property>
<property name="rightMargin" >
<number>3</number>
</property>
<property name="bottomMargin" >
<number>3</number>
</property>
<item>
<widget class="QTableWidget" name="log_incoming" >
<property name="autoFillBackground" >
<bool>false</bool>
</property>
<property name="editTriggers" >
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors" >
<bool>true</bool>
</property>
<property name="selectionMode" >
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior" >
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="columnCount" >
<number>3</number>
</property>
<column>
<property name="text" >
<string>Caller</string>
</property>
</column>
<column>
<property name="text" >
<string>Called</string>
</property>
</column>
<column>
<property name="text" >
<string>Duration</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>0</number>
</property>
<property name="leftMargin" >
<number>3</number>
</property>
<property name="topMargin" >
<number>3</number>
</property>
<property name="rightMargin" >
<number>3</number>
</property>
<property name="bottomMargin" >
<number>3</number>
</property>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="log_in_call" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>64</width>
<height>25</height>
</size>
</property>
<property name="toolTip" >
<string>Call back this number</string>
</property>
<property name="text" >
<string>Call</string>
</property>
<property name="icon" >
<iconset>phone.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="log_in_clear" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>64</width>
<height>25</height>
</size>
</property>
<property name="toolTip" >
<string>Clear all incoming calls log</string>
</property>
<property name="text" >
<string>Clear</string>
</property>
<property name="icon" >
<iconset>cdr_clear.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
<property name="_yate_identity" stdset="0" >
<string>clear:log_incoming</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="log_in_contact" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>64</width>
<height>25</height>
</size>
</property>
<property name="toolTip" >
<string>Turn this number into a contact</string>
</property>
<property name="text" >
<string>Contact</string>
</property>
<property name="icon" >
<iconset>book.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="log_clear" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>70</width>
<height>25</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>70</width>
<height>25</height>
</size>
</property>
<property name="toolTip" >
<string>Clear all calls log</string>
</property>
<property name="text" >
<string>Clear</string>
</property>
<property name="icon" >
<iconset>cdr_clear.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
<property name="_yate_identity" stdset="0" >
<string>clear:log:</string>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QPushButton" name="log_del" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>70</width>
<height>25</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>70</width>
<height>25</height>
</size>
</property>
<property name="toolTip" >
<string>Delete the selected call log</string>
</property>
<property name="text" >
<string>Delete</string>
</property>
<property name="icon" >
<iconset>close.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
<property name="_yate_identity" stdset="0" >
<string>deleteselecteditem:log:</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="log_contact" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>70</width>
<height>25</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>70</width>
<height>25</height>
</size>
</property>
<property name="toolTip" >
<string>Turn this number into a contact</string>
</property>
<property name="text" >
<string>Contact</string>
</property>
<property name="icon" >
<iconset>book.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
@ -2318,6 +2102,9 @@
<height>20</height>
</size>
</property>
<property name="_yate_identity" stdset="0" >
<string>deleteselecteditem:accounts:</string>
</property>
</widget>
</item>
<item>
@ -2421,7 +2208,7 @@
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="columnCount" >
<number>5</number>
<number>2</number>
</property>
<column>
<property name="text" >
@ -2433,21 +2220,6 @@
<string>Number/URI</string>
</property>
</column>
<column>
<property name="text" >
<string>hidden:account</string>
</property>
</column>
<column>
<property name="text" >
<string>hidden:protocol</string>
</property>
</column>
<column>
<property name="text" >
<string>hidden:editable</string>
</property>
</column>
</widget>
</item>
<item>
@ -2584,6 +2356,9 @@
<height>20</height>
</size>
</property>
<property name="_yate_identity" stdset="0" >
<string>deleteselecteditem:contacts:</string>
</property>
</widget>
</item>
<item>

View File

@ -2157,7 +2157,15 @@ public:
* @param update True to update the interface
* @return True
*/
virtual bool callLogUpdate(NamedList& params, bool save, bool update)
virtual bool callLogUpdate(const NamedList& params, bool save, bool update)
{ return false; }
/**
* Remove a call log item
* @param billid The bill id of the call
* @return True on success
*/
virtual bool callLogDelete(const String& billid)
{ return false; }
/**
@ -2364,6 +2372,29 @@ public:
*/
virtual void destruct();
/**
* Retrieve the remote party from CDR parameters
* @param params CDR parameters
* @param outgoing True if the call was an outgoing one
* @return The remote party (may be empty)
*/
static const String& cdrRemoteParty(const NamedList& params, bool outgoing)
{ return outgoing ? params["called"] : params["caller"]; }
/**
* Retrieve the remote party from CDR parameters
* @param params CDR parameters
* @return The remote party (may be empty)
*/
static const String& cdrRemoteParty(const NamedList& params) {
const String& dir = params["direction"];
if (dir == "incoming")
return cdrRemoteParty(params,true);
if (dir == "outgoing")
return cdrRemoteParty(params,false);
return String::empty();
}
/**
* Init static logic lists.
* Called by the client when start running
@ -2421,6 +2452,11 @@ public:
*/
DefaultLogic(const char* name = "default", int prio = -100);
/**
* Destructor
*/
~DefaultLogic();
/**
* Handle actions from user interface
* @param wnd The window in which the user did something
@ -2597,7 +2633,14 @@ public:
* @param update True to update the interface
* @return True
*/
virtual bool callLogUpdate(NamedList& params, bool save, bool update);
virtual bool callLogUpdate(const NamedList& params, bool save, bool update);
/**
* Remove a call log item
* @param billid The bill id of the call
* @return True on success
*/
virtual bool callLogDelete(const String& billid);
/**
* Clear the specified log and the entries from the history file and save the history file
@ -2694,6 +2737,14 @@ public:
*/
virtual bool handleUserNotify(Message& msg, bool& stopLogic);
/**
* Process user.roster message
* @param msg Received message
* @param stopLogic Set to true on exit to tell the client to stop asking other logics
* @return True to stop further processing by the engine
*/
virtual bool handleUserRoster(Message& msg, bool& stopLogic);
/**
* Process resource.notify message
* @param msg Received message
@ -2773,9 +2824,55 @@ protected:
*/
virtual void channelSelectionChanged(const String& old);
/**
* Fill contact edit/delete active parameters
* @param list Destination list
* @param active True to activate, false to deactivate
* @param item Optional selected item to check in contacts list if active
*/
virtual void fillContactEditActive(NamedList& list, bool active, const String* item = 0);
/**
* Fill log contact active parameter
* @param list Destination list
* @param active True to activate, false to deactivate
* @param item Optional selected item to check in calls log list if active
*/
virtual void fillLogContactActive(NamedList& list, bool active, const String* item = 0);
/**
* Clear a list/table. Handle specific lists like CDR, accounts, contacts
* @param action The list. May contain an optional confirmation text to display.
* Format: 'list_name[:confirmation_text]'
* @param wnd Window owning the list/table
* @return True on success
*/
virtual bool clearList(const String& action, Window* wnd);
/**
* Delete a list/table item. Handle specific lists like CDR, accounts, contacts
* @param list The list
* @param item Item to delete
* @param wnd Window owning the list/table
* @return True on success
*/
virtual bool deleteItem(const String& list, const String& item, Window* wnd);
/**
* Handle list/table selection deletion.
* Handle specific lists like CDR, accounts, contacts
* @param action Action to handle. May contain an optional confirmation text to display.
* Format: 'list_name[:confirmation_text]'
* @param wnd Window owning the list/table
* @return True on success
*/
virtual bool deleteSelectedItem(const String& action, Window* wnd);
String m_selectedChannel; // The currently selected channel
String m_transferInitiated; // Tranfer initiated id
bool m_accShowAdvanced; // Show/hide the account advanced options
private:
ClientAccountList* m_accounts; // Accounts list (always valid)
};
@ -2793,29 +2890,25 @@ public:
* @param user The account's username
* @param host The account's host
* @param startup True if the account should login at startup
* @param contact Optional account's own contact
*/
ClientAccount(const char* proto, const char* user,
const char* host, bool startup);
ClientAccount(const char* proto, const char* user, const char* host,
bool startup, ClientContact* contact = 0);
/**
* Constructor. Build an account from a list of parameters
* @param params The list of parameters used to build this account
* @param params The list of parameters used to build this account.
* The list's name will be used as account id
* @param contact Optional account's own contact
*/
ClientAccount(const NamedList& params);
ClientAccount(const NamedList& params, ClientContact* contact = 0);
/**
* Get this account's URI
* @return This account's URI
* Get this account's parameters
* @return This account's parameter list
*/
inline const URI& uri() const
{ return m_uri; }
/**
* Get this account's id
* @return This account's id
*/
inline const URI& id() const
{ return m_id; }
inline const NamedList& params() const
{ return m_params; }
/**
* Get this account's contacts. The caller should lock the account while browsing the list
@ -2824,12 +2917,46 @@ public:
inline ObjList& contacts()
{ return m_contacts; }
/**
* Retrieve account own contact
* @return ClientContact pointer
*/
inline ClientContact* contact() const
{ return m_contact; }
/**
* Set or reset account own contact
* @param contact New account contact (may be NULL to reset it)
*/
void setContact(ClientContact* contact);
/**
* Retrieve the account's protocol
* @return The account's protocol
*/
inline const String& protocol() const
{ return m_params["protocol"]; }
/**
* Check if the account should be logged in at startup
* @return True if the account should be logged in at startup
*/
inline bool startup() const
{ return m_params.getBoolValue("enabled",true); }
/**
* Set the account's startup login flag
* @param ok The account's startup login flag value
*/
inline void startup(bool ok)
{ m_params.setParam("enabled",String::boolText(ok)); }
/**
* Get a string representation of this object
* @return The account's compare id
*/
virtual const String& toString() const
{ return m_id; }
{ return m_params; }
/**
* Get this account's resource
@ -2850,14 +2977,33 @@ public:
*/
void setResource(ClientResource* res);
/**
* Save or remove this account to/from client accounts file
* @param ok True to save, false to remove
* @param savePwd True to save the password
* @return True on success
*/
bool save(bool ok = true, bool savePwd = true);
/**
* Find a contact by its id
* @param id The id of the desired contact
* @param ref True to obtain a referenced pointer
* @return ClientContact pointer or 0 if not found
* @return ClientContact pointer (may be account's own contact) or 0 if not found
*/
virtual ClientContact* findContact(const String& id, bool ref = false);
/**
* Find a contact by name and/or uri. Account own contact is ignored
* @param name Optional name to check (may be a pointer to an empty string)
* @param uri Optional uri to check (may be a pointer to an empty string)
* @param skipId Optional contact to skip
* @param ref True to obtain a referenced pointer
* @return ClientContact pointer or 0 if not found
*/
virtual ClientContact* findContact(const String* name = 0, const String* uri = 0,
const String* skipId = 0, bool ref = false);
/**
* Find a contact having a given id and resource
* @param id The id of the desired contact
@ -2865,9 +3011,17 @@ public:
* @param ref True to obtain a referenced pointer
* @return ClientContact pointer or 0 if not found
*/
virtual ClientContact* findContact(const String& id, const String& resid,
virtual ClientContact* findContact(const String& id, const String& resid,
bool ref = false);
/**
* Find a contact by its URI (build an id from account and uri)
* @param uri The contact's uri
* @param ref True to get a referenced pointer
* @return ClientContact pointer or 0 if not found
*/
virtual ClientContact* findContactByUri(const String& uri, bool ref = false);
/**
* Build a contact and append it to the list
* @param id The contact's id
@ -2900,44 +3054,24 @@ public:
virtual Message* userlogin(bool login, const char* msg = "user.login");
/**
* Build an account id
* @param dest Destination URI
* @param proto The account's protocol
* @param user The account's username
* @param host The account's host
* Fill a list used to update a account's list item
* @param list Parameter list to fill
*/
static void buildAccountId(URI& dest, const char* proto, const char* user, const char* host) {
URI u(proto,user,host);
dest = u.toLower();
}
virtual void fillItemParams(NamedList& list);
String m_password; // Account's password
String m_server; // Account's server (name or IP address)
int m_port; // Server's port used to connect to
String m_options; // Account's options
bool m_startup; // Enable/disable flag
String m_outbound; // Outbound server (if any)
int m_expires; // Registration interval for protocols supporting it
bool m_connected; // Logged in/out flag
NamedList m_params; // Account parameters
protected:
// Remove from owner. Release data
virtual void destroyed();
// Method used by the contact to append itself to this account's list
virtual void appendContact(ClientContact* contact);
// Set ID and URI
inline void setIdUri(const char* proto, const char* user,
const char* host) {
buildAccountId(m_id,proto,user,host);
m_uri = String(user) + "@" + host;
}
URI m_id; // The account's id
URI m_uri; // Account's URI
ObjList m_contacts; // Account's contacts
private:
ClientResource* m_resource; // Account's resource
ClientContact* m_contact; // Account's contact data
};
/**
@ -2983,6 +3117,14 @@ public:
*/
bool isLocalContact(ClientContact* c) const;
/**
* Check if a contact is locally stored
* @param id Contact id to check
* @return True if the contact owner is the account owning locally stored contacts
*/
inline bool isLocalContact(const String& id) const
{ return m_localContacts && m_localContacts->findContact(id); }
/**
* Find an account
* @param id The account's id
@ -2991,6 +3133,16 @@ public:
*/
virtual ClientAccount* findAccount(const String& id, bool ref = false);
/**
* Find an account's contact by its URI (build an id from account and uri)
* @param account The account's id
* @param uri The contact's uri
* @param ref True to get a referenced pointer
* @return ClientContact pointer or 0 if not found
*/
virtual ClientContact* findContactByUri(const String& account, const String& uri,
bool ref = false);
/**
* Find an account's contact
* @param account The account's id
@ -3008,6 +3160,25 @@ public:
*/
virtual ClientContact* findContact(const String& builtId, bool ref = false);
/**
* Find a contact an instance id
* @param id The id
* @param instance Optional pointer to String to be filled with instance id
* @param ref True to get a referenced pointer
* @return ClientContact pointer or 0 if not found
*/
virtual ClientContact* findContactByInstance(const String& id, String* instance = 0,
bool ref = false);
/**
* Check if there is a single registered account and return it
* @param skipProto Optional account protocol to skip
* @param ref True to get a referenced pointer
* @return ClientAccount pointer or 0 if not found
*/
virtual ClientAccount* findSingleRegAccount(const String* skipProto = 0,
bool ref = false);
/**
* Append a new account. The account's reference counter is increased before
* @param account The account to append
@ -3050,12 +3221,15 @@ public:
/**
* Constructor. Build a contact from a list of parameters.
. Append itself to the owner's list
* Append itself to the owner's list
* @param owner The contact's owner
* @param params The list of parameters used to build this contact
* @param id Optional contact id
* @param uri Optional contact URI
* @param chat True to create the chat window
*/
ClientContact(ClientAccount* owner, NamedList& params, bool chat);
ClientContact(ClientAccount* owner, const NamedList& params, const char* id = 0,
const char* uri = 0, bool chat = false);
/**
* Get this contact's account
@ -3078,6 +3252,13 @@ public:
inline const URI& uri() const
{ return m_uri; }
/**
* Set this contact's URI
* @param u New contact URI
*/
inline void setUri(const char* u)
{ m_uri = u; }
/**
* Get the resource list of this contact
* @return The resource list of this contact
@ -3085,6 +3266,13 @@ public:
inline ObjList& resources()
{ return m_resources; }
/**
* Check if the contact is online (has at least 1 resource in list)
* @return True if the contact is online
*/
inline bool online() const
{ return 0 != m_resources.skipNull(); }
/**
* Get the group list of this contact
* @return The group list of this contact
@ -3092,6 +3280,17 @@ public:
inline ObjList& groups()
{ return m_groups; }
/**
* Remove account prefix from contact id and URI unescape the result
* @param buf Destination buffer
*/
inline void getContactSection(String& buf) {
String pref;
buf = toString();
buf.startSkip(buildContactId(pref,accountName(),String::empty()),false);
buf = buf.uriUnescape();
}
/**
* Get a string representation of this object
* @return The contact's id
@ -3100,11 +3299,15 @@ public:
{ return m_id; }
/**
* Build a contact id to be used in UI
* Build a contact instance id to be used in UI
* @param dest Destination string
* @param inst Instance name
* @return Destination string
*/
inline void buildContactId(String& dest)
{ buildContactId(dest,m_owner ? m_owner->toString() : String::empty(),m_id); }
inline String& buildInstanceId(String& dest, const String& inst = String::empty()) {
dest << m_id << "|" << inst.uriEscape('|');
return dest;
}
/**
* Build a string from prefix and contact id hash
@ -3245,32 +3448,41 @@ public:
{ return wnd && wnd->toString().startsWith(s_chatPrefix); }
/**
* Build a contact id to be used in UI
* Build a contact id to be used in UI (all strings are URI escaped using extra '|' character)
* @param dest Destination string
* @param account Account owning the contact
* @param contact The contact's id
* @return Destination string
*/
static inline void buildContactId(String& dest, const String& account,
const String& contact)
{ dest << String(account).toLower() << "|" << String(contact).toLower(); }
static inline String& buildContactId(String& dest, const String& account,
const String& contact) {
dest << account.uriEscape('|') << "|" << String::uriEscape(contact,'|').toLower();
return dest;
}
/**
* Split a contact id
* Retrieve the account part of a contact id
* @param src Source string
* @param account Account name
* @param contact Contact's name
* @param account Account id (URI unescaped)
*/
static inline void splitContactId(const String& src, String& account,
String& contact) {
static inline void splitContactId(const String& src, String& account) {
int pos = src.find('|');
if (pos < 1) {
account = src;
return;
}
account = src.substr(0,pos);
contact = src.substr(pos + 1);
if (pos >= 0)
account = src.substr(0,pos).uriUnescape();
else
account = src.uriUnescape();
}
/**
* Split a contact instance id in account/contact/instance parts
* @param src Source string
* @param account Account id (URI unescaped)
* @param contact Contact id
* @param instance Optional pointer to a String to be filled with instance id (URI unescaped)
*/
static void splitContactInstanceId(const String& src, String& account,
String& contact, String* instance = 0);
// Chat window prefix
static String s_chatPrefix;
@ -3400,7 +3612,7 @@ public:
* @param text Resource status text
* @return True if changed
*/
inline bool setStatusText(const String& text) {
inline bool setStatusText(const String& text = String::empty()) {
if (m_text == text)
return false;
m_text = text;
@ -3413,7 +3625,7 @@ public:
static const TokenDict s_statusName[];
String m_id; // The resource id
String m_name; // Account's display name
String m_name; // Resource display name
bool m_audio; // Audio capability flag
int m_priority; // Resource priority
int m_status; // Resource status