Chat rooms can now be added to contacts list. Save them locally and to server as private data. Retrieve chat rooms private data when connected.

git-svn-id: http://yate.null.ro/svn/yate/trunk@4209 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2011-03-24 13:30:05 +00:00
parent 8fa7fcf95a
commit 4bc643c0f3
11 changed files with 1996 additions and 158 deletions

View File

@ -3894,6 +3894,13 @@ MucRoom* ClientAccount::findRoomByUri(const String& uri, bool ref)
return findRoom(id,ref);
}
// Find any contact (regular or MUC room) by its id
ClientContact* ClientAccount::findAnyContact(const String& id, bool ref)
{
ClientContact* c = findContact(id,ref);
return c ? c : findRoom(id,ref);
}
// Build a contact and append it to the list
ClientContact* ClientAccount::appendContact(const String& id, const char* name,
const char* uri)
@ -3940,6 +3947,24 @@ ClientContact* ClientAccount::removeContact(const String& id, bool delObj)
return c;
}
// Clear MUC rooms
void ClientAccount::clearRooms(bool saved, bool temp)
{
if (!(saved || temp))
return;
Lock lock(this);
ListIterator iter(m_mucs);
for (GenObject* gen = 0; 0 != (gen = iter.get());) {
MucRoom* r = static_cast<MucRoom*>(gen);
if (r->local() || r->remote()) {
if (saved)
m_mucs.remove(r);
}
else if (temp)
m_mucs.remove(r);
}
}
// Build a login/logout message from account's data
Message* ClientAccount::userlogin(bool login, const char* msg)
{
@ -3953,6 +3978,44 @@ Message* ClientAccount::userlogin(bool login, const char* msg)
return m;
}
// Build a message used to update or query account userdata
Message* ClientAccount::userData(bool update, const String& data, const char* msg)
{
Message* m = Client::buildMessage(msg,toString(),update ? "update" : "query");
m->addParam("data",data,false);
if (!update || data != "chatrooms")
return m;
m->setParam("data.count","0");
unsigned int n = 0;
Lock lock(this);
for (ObjList* o = m_mucs.skipNull(); o; o = o->skipNext()) {
MucRoom* r = static_cast<MucRoom*>(o->get());
if (!r->remote())
continue;
String prefix;
prefix << "data." << ++n;
m->addParam(prefix,r->uri());
prefix << ".";
m->addParam(prefix + "name",r->m_name,false);
if (r->m_password) {
Base64 b((void*)r->m_password.c_str(),r->m_password.length());
String tmp;
b.encode(tmp);
m->addParam(prefix + "password",tmp);
}
for (ObjList* o = r->groups().skipNull(); o; o = o->skipNext())
m->addParam(prefix + "group",o->get()->toString(),false);
NamedIterator iter(r->m_params);
for (const NamedString* ns = 0; 0 != (ns = iter.get());) {
// Skip local/remote params
if (ns->name() != "local" && ns->name() != "remote")
m->addParam(prefix + ns->name(),*ns);
}
}
m->setParam("data.count",String(n));
return m;
}
// Fill a list used to update an account list item
void ClientAccount::fillItemParams(NamedList& list)
{
@ -3964,6 +4027,225 @@ void ClientAccount::fillItemParams(NamedList& list)
list.addParam(status);
}
// Utility used in ClientAccount::setupDataDir
static bool showAccError(ClientAccount* a, String* errStr, const String& fail,
const char* what, int error = 0, const char* errorStr = 0)
{
String tmp;
if (!errStr)
errStr = &tmp;
if (error) {
Thread::errorString(*errStr,error);
*errStr = String(error) + " " + *errStr;
}
else
*errStr = errorStr;
*errStr = fail + " '" + what + "': " + *errStr;
Debug(ClientDriver::self(),DebugWarn,"Account(%s) %s [%p]",
a->toString().c_str(),errStr->c_str(),a);
return false;
}
// Set account data directory. Make sure it exists.
// Move all files from the old one if changed
bool ClientAccount::setupDataDir(String* errStr, bool saveAcc)
{
String dir;
String user = m_params["username"];
user.toLower();
String domain = m_params.getValue("domain",m_params.getValue("server"));
domain.toLower();
dir << protocol().hash() << "_" << user.hash() << "_" << domain.hash();
if (dataDir() == dir) {
String s;
s << Engine::configPath(true) << Engine::pathSeparator() << dataDir();
ObjList d;
ObjList f;
File::listDirectory(s,&d,&f);
if (d.find(dataDir()))
return true;
if (f.find(dataDir()))
return showAccError(this,errStr,"Failed to create directory",s,0,
"A file with the same name already exists");
// Not found: clear old directory
m_params.clearParam("datadirectory");
}
String path = Engine::configPath(true);
// Check if already there
int error = 0;
ObjList dirs;
ObjList files;
File::listDirectory(path,&dirs,&files);
if (error)
return showAccError(this,errStr,"Failed to list directory",path,error);
String fullPath = path + Engine::pathSeparator() + dir;
if (files.find(dir))
return showAccError(this,errStr,"Failed to create directory",fullPath,0,
"A file with the same name already exists");
const String& existing = dataDir();
ObjList* oldDir = existing ? dirs.find(existing) : 0;
if (dirs.find(dir)) {
if (oldDir) {
// Move dirs and files from old directory
String old = path + Engine::pathSeparator() + existing;
ObjList all;
File::listDirectory(old,&all,&all,&error);
if (!error) {
bool ok = true;
for (ObjList* o = all.skipNull(); o; o = o->skipNext()) {
String* item = static_cast<String*>(o->get());
String oldItem = old + Engine::pathSeparator() + *item;
String newItem = fullPath + Engine::pathSeparator() + *item;
File::rename(oldItem,newItem,&error);
if (!error)
continue;
ok = false;
String tmp;
Thread::errorString(tmp,error);
Debug(ClientDriver::self(),DebugWarn,
"Account(%s) failed to move '%s' to '%s': %d %s [%p]",
toString().c_str(),oldItem.c_str(),newItem.c_str(),
error,tmp.c_str(),this);
error = 0;
}
// Delete it if all moved
if (ok) {
File::rmDir(old,&error);
if (error)
showAccError(this,errStr,"Failed to delete directory",old,error);
}
}
else
showAccError(this,errStr,"Failed to list directory",old,error);
}
}
else {
if (oldDir) {
// Rename it
String old = path + Engine::pathSeparator() + existing;
File::rename(old,fullPath,&error);
if (error)
return showAccError(this,errStr,"Failed to rename existing directory",
old,error);
}
else {
// Create a new one
File::mkDir(fullPath,&error);
if (error)
return showAccError(this,errStr,"Failed to create directory",
fullPath,error);
}
}
m_params.setParam("datadirectory",dir);
if (saveAcc) {
NamedList* sect = Client::s_accounts.getSection(toString());
if (sect) {
sect->setParam("datadirectory",dir);
Client::s_accounts.save();
}
}
// Set account meta data
loadDataDirCfg();
NamedList* sect = m_cfg.createSection("general");
sect->setParam("account",toString());
sect->copyParams(m_params,"protocol,username,domain,server");
m_cfg.save();
return true;
}
// Load configuration file from data directory
bool ClientAccount::loadDataDirCfg(Configuration* cfg, const char* file)
{
if (TelEngine::null(file))
return false;
if (!cfg)
cfg = &m_cfg;
if (!dataDir())
setupDataDir(0,false);
const String& dir = dataDir();
if (!dir)
return false;
*cfg = "";
*cfg << Engine::configPath(true) + Engine::pathSeparator() + dir;
*cfg << Engine::pathSeparator() << file;
return cfg->load();
}
// Clear account data directory
bool ClientAccount::clearDataDir(String* errStr)
{
if (!dataDir())
setupDataDir(0,false);
const String& dir = dataDir();
if (!dir)
return false;
// Check base path
String tmp(Engine::configPath(true));
ObjList dirs;
File::listDirectory(tmp,&dirs,0);
if (!dirs.find(dir))
return true;
// Delete files
tmp << Engine::pathSeparator() << dir << Engine::pathSeparator();
int error = 0;
bool ok = false;
ObjList files;
if (File::listDirectory(tmp,0,&files,&error)) {
for (ObjList* o = files.skipNull(); o; o = o->skipNext()) {
String file(tmp + o->get()->toString());
int err = 0;
if (!File::remove(file,&err)) {
if (!error)
error = err;
}
}
if (!error)
ok = File::rmDir(tmp,&error);
}
return ok ? ok : showAccError(this,errStr,"Failed to clear data directory",tmp,error);
}
// Load contacts from configuration file
void ClientAccount::loadContacts(Configuration* cfg)
{
if (!cfg)
cfg = &m_cfg;
unsigned int n = cfg->sections();
for (unsigned int i = 0; i < n; i++) {
NamedList* sect = cfg->getSection(i);
if (!(sect && sect->c_str()))
continue;
const String& type = (*sect)["type"];
if (type == "groupchat") {
String id;
ClientContact::buildContactId(id,toString(),*sect);
MucRoom* room = findRoom(id);
if (!room)
room = new MucRoom(this,id,0,*sect);
room->groups().clear();
NamedIterator iter(*sect);
for (const NamedString* ns = 0; 0 != (ns = iter.get());) {
if (ns->name() == "type")
continue;
if (ns->name() == "name")
room->m_name = *ns;
else if (ns->name() == "password")
room->m_password = *ns;
else if (ns->name() == "group") {
if (*ns)
room->appendGroup(*ns);
}
else
room->m_params.setParam(ns->name(),*ns);
}
room->setLocal(true);
Debug(ClientDriver::self(),DebugAll,
"Account(%s) loaded MUC room '%s' [%p]",
toString().c_str(),room->uri().c_str(),this);
}
}
}
// Remove from owner. Release data
void ClientAccount::destroyed()
{
@ -4087,6 +4369,16 @@ MucRoom* ClientAccountList::findRoomByMember(const String& id, bool ref)
return acc ? acc->findRoom(contact,ref) : 0;
}
// Find any contact (regular or MUC room) by its id
ClientContact* ClientAccountList::findAnyContact(const String& id, bool ref)
{
String account;
ClientContact::splitContactId(id,account);
Lock lock(this);
ClientAccount* acc = findAccount(account);
return acc ? acc->findAnyContact(id,ref) : 0;
}
// Check if there is a single registered account and return it
ClientAccount* ClientAccountList::findSingleRegAccount(const String* skipProto, bool ref)
{
@ -4136,8 +4428,8 @@ void ClientAccountList::removeAccount(const String& id)
// Constructor. Append itself to the owner's list
ClientContact::ClientContact(ClientAccount* owner, const char* id, const char* name,
const char* uri)
: m_name(name ? name : id), m_owner(owner), m_online(false), m_uri(uri),
m_dockedChat(false)
: m_name(name ? name : id), m_params(""), m_owner(owner), m_online(false),
m_uri(uri), m_dockedChat(false)
{
m_dockedChat = Client::valid() && Client::self()->getBoolOpt(Client::OptDockedChat);
m_id = id ? id : uri;
@ -4152,7 +4444,7 @@ ClientContact::ClientContact(ClientAccount* owner, const char* id, const char* n
// Constructor. Build a contact from a list of parameters.
ClientContact::ClientContact(ClientAccount* owner, const NamedList& params, const char* id,
const char* uri)
: m_name(params.getValue("name",params)),
: m_name(params.getValue("name",params)), m_params(""),
m_owner(owner), m_online(false), m_uri(uri), m_dockedChat(false)
{
m_dockedChat = Client::valid() && Client::self()->getBoolOpt(Client::OptDockedChat);
@ -4167,7 +4459,7 @@ ClientContact::ClientContact(ClientAccount* owner, const NamedList& params, cons
// Constructor. Append itself to the owner's list
ClientContact::ClientContact(ClientAccount* owner, const char* id, bool mucRoom)
: m_owner(owner), m_online(false), m_id(id), m_dockedChat(false)
: m_params(""), m_owner(owner), m_online(false), m_id(id), m_dockedChat(false)
{
if (m_owner)
m_owner->appendContact(this,mucRoom);

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

View File

@ -0,0 +1,676 @@
<ui version="4.0" >
<class>chatroomedit</class>
<widget class="QWidget" name="chatroomedit" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>268</height>
</rect>
</property>
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>400</width>
<height>200</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>400</width>
<height>268</height>
</size>
</property>
<property name="windowIcon" >
<iconset>muc.png</iconset>
</property>
<property name="styleSheet" >
<string>QWidget#chatroomedit {
background-color:#e0dfe3;
}
</string>
</property>
<property name="_yate_windowflags" stdset="0" >
<string>sysmenu,title,minimize,close</string>
</property>
<property name="_yate_destroyonhide" stdset="0" >
<bool>true</bool>
</property>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>4</number>
</property>
<property name="leftMargin" >
<number>6</number>
</property>
<property name="topMargin" >
<number>4</number>
</property>
<property name="rightMargin" >
<number>6</number>
</property>
<property name="bottomMargin" >
<number>4</number>
</property>
<item>
<layout class="QHBoxLayout" >
<property name="topMargin" >
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_account" >
<property name="enabled" >
<bool>true</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>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>70</width>
<height>22</height>
</size>
</property>
<property name="text" >
<string>Account:</string>
</property>
<property name="indent" >
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="chataccount" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="chatcontact_account" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
<property name="readOnly" >
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="label_room" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>70</width>
<height>16777215</height>
</size>
</property>
<property name="text" >
<string>Room:</string>
</property>
<property name="indent" >
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_uri" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>16</width>
<height>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>2</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="QLineEdit" name="username" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>100</width>
<height>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>100</width>
<height>22</height>
</size>
</property>
<property name="_yate_textchangednotify" stdset="0" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>@</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="domain" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>78</width>
<height>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLineEdit" name="chatcontact_uri" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
<property name="readOnly" >
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="topMargin" >
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_nick_2" >
<property name="enabled" >
<bool>true</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>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>70</width>
<height>22</height>
</size>
</property>
<property name="styleSheet" >
<string>QLabel:disabled {color: red;}</string>
</property>
<property name="text" >
<string>Name:</string>
</property>
<property name="indent" >
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="name" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="topMargin" >
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_nick" >
<property name="enabled" >
<bool>true</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>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>70</width>
<height>22</height>
</size>
</property>
<property name="styleSheet" >
<string>QLabel:disabled {color: red;}</string>
</property>
<property name="text" >
<string>Nick:</string>
</property>
<property name="indent" >
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="nick" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="topMargin" >
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_password" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>70</width>
<height>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>70</width>
<height>22</height>
</size>
</property>
<property name="text" >
<string>Password:</string>
</property>
<property name="indent" >
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="password" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
<property name="echoMode" >
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="topMargin" >
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_group" >
<property name="enabled" >
<bool>true</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>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>70</width>
<height>22</height>
</size>
</property>
<property name="styleSheet" >
<string>QLabel:disabled {color: red;}</string>
</property>
<property name="text" >
<string>Group:</string>
</property>
<property name="indent" >
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="group" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="history" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
<property name="text" >
<string>Retrieve history</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="leftMargin" >
<number>18</number>
</property>
<item>
<widget class="QCheckBox" name="historylast" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
<property name="text" >
<string>Retrieve last</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="historylast_value" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
<property name="suffix" >
<string> minutes</string>
</property>
<property name="minimum" >
<number>1</number>
</property>
<property name="maximum" >
<number>1440</number>
</property>
<property name="singleStep" >
<number>5</number>
</property>
<property name="value" >
<number>30</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Line" name="line" >
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>2</height>
</size>
</property>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>4</number>
</property>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="chatroomedit_ok" >
<property name="text" >
<string>Ok</string>
</property>
<property name="icon" >
<iconset>ok.png</iconset>
</property>
<property name="shortcut" >
<string>Return</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="button_hide" >
<property name="text" >
<string>Cancel</string>
</property>
<property name="icon" >
<iconset>close.png</iconset>
</property>
<property name="shortcut" >
<string>Esc</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,146 @@
<ui version="4.0" >
<class>contactlist_chatroom</class>
<widget class="QWidget" name="contactlist_chatroom" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>471</width>
<height>42</height>
</rect>
</property>
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>0</width>
<height>42</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>42</height>
</size>
</property>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>1</number>
</property>
<property name="leftMargin" >
<number>1</number>
</property>
<property name="topMargin" >
<number>1</number>
</property>
<property name="rightMargin" >
<number>1</number>
</property>
<property name="bottomMargin" >
<number>4</number>
</property>
<item>
<layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="status_image" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
<property name="pixmap" >
<pixmap>muc_16.png</pixmap>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="name" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>20</height>
</size>
</property>
<property name="styleSheet" >
<string>QLabel {
font-size:12px;
}</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>0</number>
</property>
<property name="leftMargin" >
<number>21</number>
</property>
<item>
<widget class="QLabel" name="status_text" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>0</width>
<height>12</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>12</height>
</size>
</property>
<property name="styleSheet" >
<string>QLabel {
font-size:10px;
}</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -129,6 +129,34 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="room_save_btn" >
<property name="minimumSize" >
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="autoRaise" >
<bool>true</bool>
</property>
<property name="_yate_identity" stdset="0" >
<string>room_save</string>
</property>
<property name="_yate_setaction" stdset="0" >
<string>room_save</string>
</property>
<property name="_yate_noautoconnect" stdset="0" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="room_showlog_btn" >
<property name="minimumSize" >
@ -684,6 +712,17 @@
<string>room_showlog</string>
</property>
</action>
<action name="room_save" >
<property name="icon" >
<iconset>save.png</iconset>
</property>
<property name="text" >
<string>Save chat room contact</string>
</property>
<property name="_yate_identity" stdset="0" >
<string>room_save</string>
</property>
</action>
</widget>
<tabstops>
<tabstop>message</tabstop>

View File

@ -106,6 +106,11 @@ enabled=no
save=false
description=contactedit.ui
[chatroomedit]
enabled=no
save=false
description=chatroomedit.ui
[contactinfo]
enabled=no
save=false

View File

@ -130,6 +130,7 @@
<addaction name="menuSubscription" />
<addaction name="separator" />
<addaction name="chatcontact_new" />
<addaction name="chatroom_new" />
<addaction name="separator" />
<addaction name="chatcontact_showoffline" />
<addaction name="chatcontact_flatlist" />
@ -203,14 +204,18 @@
<string>property:_yate_nogroup_caption=Not set</string>
<string>property:_yate_itemui=contact:contactlist_contact.ui</string>
<string>property:_yate_itemui=group:contactlist_group.ui</string>
<string>property:_yate_itemui=chatroom:contactlist_chatroom.ui</string>
<string>property:_yate_itemstyle=contact:QWidget#${name}{background:white;}</string>
<string>property:_yate_itemstyle=group:QWidget#${name}{background:lightgrey;}</string>
<string>property:_yate_itemstyle=chatroom:QWidget#${name}{background:white;}</string>
<string>property:_yate_itemselectedstyle=contact:QWidget#${name}{background:lightblue;}</string>
<string>property:_yate_itemselectedstyle=group:QWidget#${name}{background:lightgrey;}</string>
<string>property:_yate_itemselectedstyle=chatroom:QWidget#${name}{background:lightblue;}</string>
<string>property:_yate_itemstatewidget=group:state</string>
<string>property:_yate_itemexpandedimage=group:expanded.png</string>
<string>property:_yate_itemcollapsedimage=group:collapsed.png</string>
<string>property:_yate_itemtooltip=contact:&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">\np, li { white-space: pre-wrap; }\n&lt;/style>&lt;/head>&lt;body style=" font-family:'Arial'; font-size:10pt; font-weight:400; font-style:normal;">&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;span style=" font-size:14pt; font-weight:600;">${name}&lt;/span>&lt;/p>&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">${status_text}&lt;/p>&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">${contact}&lt;/p>&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Account: ${account}&lt;/p>&lt;/body>&lt;/html></string>
<string>property:_yate_itemtooltip=chatroom:&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">\np, li { white-space: pre-wrap; }\n&lt;/style>&lt;/head>&lt;body style=" font-family:'Arial'; font-size:10pt; font-weight:400; font-style:normal;">&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;span style=" font-size:14pt; font-weight:600;">${name}&lt;/span>&lt;/p>&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">${status_text}&lt;/p>&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">${contact}&lt;/p>&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Account: ${account}&lt;/p>&lt;/body>&lt;/html></string>
<string>groupcount=count</string>
</stringlist>
</property>
@ -1973,6 +1978,7 @@ QTextEdit {
<string>delete_item_action=deleteitem</string>
<string>property:_yate_hidewndwhenempty=false</string>
<string>property:_yate_hidewidgetwhenempty=frame_messages</string>
<string>property:_yate_itemui=generic:messages_generic.ui</string>
<string>property:_yate_itemui=subscription:messages_okrejignore.ui</string>
<string>property:_yate_itemui=mucinvite:messages_okrejignore.ui</string>
<string>property:_yate_itemui=loginfail:messages_loginfail.ui</string>
@ -2374,6 +2380,14 @@ QTextEdit {
<string>Show log</string>
</property>
</action>
<action name="chatroom_new" >
<property name="icon" >
<iconset>addchatroom.png</iconset>
</property>
<property name="text" >
<string>Add chat room</string>
</property>
</action>
</widget>
<resources/>
<connections/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

View File

@ -791,6 +791,7 @@ public:
MsgExecute,
EngineStart,
TransferNotify,
UserData,
// Starting value for custom relays
MsgIdCount
};
@ -2618,6 +2619,24 @@ public:
*/
static void initStaticData();
/**
* Save a contact into a configuration file
* @param cfg The configuration file
* @param c The contact to save
* @param save True to save the file
* @return True on success
*/
static bool saveContact(Configuration& cfg, ClientContact* c, bool save = true);
/**
* Delete a contact from a configuration file
* @param cfg The configuration file
* @param c The contact to delete
* @param save True to save the file
* @return True on success
*/
static bool clearContact(Configuration& cfg, ClientContact* c, bool save = true);
// Account options string list
static ObjList s_accOptions;
// Parameters that are applied from provider template
@ -3121,6 +3140,26 @@ protected:
*/
virtual bool handleFileTransferNotify(Message& msg, bool& stopLogic);
/**
* Handle user.data messages.
* @param msg The message
* @param stopLogic Stop notifying other logics if set to true on return
* @return True if handled
*/
virtual bool handleUserData(Message& msg, bool& stopLogic);
/**
* Show a generic notification
* @param text Notification text
* @param account Optional concerned account
* @param contact Optional concerned contact
* @param title Notification title
*/
virtual void notifyGenericError(const String& text,
const String& account = String::empty(),
const String& contact = String::empty(),
const char* title = "Error");
/**
* Show/hide no audio notification
* @param show Show or hide notification
@ -3131,6 +3170,15 @@ protected:
virtual void notifyNoAudio(bool show, bool micOk = false, bool speakerOk = false,
ClientChannel* chan = 0);
/**
* (Un)Load account's saved chat rooms or a specific room in contact list
* @param load True to load, false to unload
* @param acc The account owning the chat rooms
* @param room The room to update, ignored if acc is not 0
*/
virtual void updateChatRoomsContactList(bool load, ClientAccount* acc,
MucRoom* room = 0);
String m_selectedChannel; // The currently selected channel
String m_transferInitiated; // Tranfer initiated id
@ -3350,6 +3398,14 @@ public:
*/
virtual MucRoom* findRoomByUri(const String& uri, bool ref = false);
/**
* Find any contact (regular or MUC room) by its id
* @param id The id of the desired contact
* @param ref True to obtain a referenced pointer
* @return ClientContact pointer (may be account's own contact) or 0 if not found
*/
virtual ClientContact* findAnyContact(const String& id, bool ref = false);
/**
* Build a contact and append it to the list
* @param id The contact's id
@ -3375,6 +3431,13 @@ public:
*/
virtual ClientContact* removeContact(const String& id, bool delObj = true);
/**
* Clear MUC rooms. This method is thread safe
* @param saved True to clear saved rooms
* @param temp True to clear temporary rooms
*/
virtual void clearRooms(bool saved, bool temp);
/**
* Build a login/logout message from account's data
* @param login True to login, false to logout
@ -3383,13 +3446,65 @@ public:
*/
virtual Message* userlogin(bool login, const char* msg = "user.login");
/**
* Build a message used to update or query account userdata.
* Add account MUC rooms if data is 'chatrooms' and update
* @param update True to update, false to query
* @param data Data to update or query
* @param msg Optional message name. Default to 'user.data'
* @return A valid Message pointer
*/
virtual Message* userData(bool update, const String& data,
const char* msg = "user.data");
/**
* Fill a list used to update a account's list item
* @param list Parameter list to fill
*/
virtual void fillItemParams(NamedList& list);
/**
* Retrieve account data directory
* @return Account data directory
*/
inline const String& dataDir() const
{ return m_params["datadirectory"]; }
/**
* Set account directory in application data directory. Make sure it exists.
* Move all files from the old one if changed
* @param errStr Optional string to be filled with error string
* @param saveAcc Save data directory parameter in client accounts
* @return True on success
*/
virtual bool setupDataDir(String* errStr = 0, bool saveAcc = true);
/**
* Load configuration file from data directory
* @param cfg Optional configuration file to load.
* Load account's conf file if 0
* @param file File name. Defaults to 'account.conf'
* @return True on success
*/
virtual bool loadDataDirCfg(Configuration* cfg = 0,
const char* file = "account.conf");
/**
* Load contacts from configuration file
* @param cfg Optional configuration file to load.
* Load from account's conf file if 0
*/
virtual void loadContacts(Configuration* cfg = 0);
/**
* Clear account data directory
* @param errStr Optional string to be filled with error string
* @return True if all files were succesfully removed
*/
virtual bool clearDataDir(String* errStr = 0);
NamedList m_params; // Account parameters
Configuration m_cfg; // Account conf file
protected:
// Remove from owner. Release data
@ -3518,6 +3633,14 @@ public:
*/
virtual MucRoom* findRoomByMember(const String& id, bool ref = false);
/**
* Find any contact (regular or MUC room) by its id
* @param id The id of the desired contact
* @param ref True to obtain a referenced pointer
* @return ClientContact pointer (may be account's own contact) or 0 if not found
*/
virtual ClientContact* findAnyContact(const String& id, bool ref = false);
/**
* Check if there is a single registered account and return it
* @param skipProto Optional account protocol to skip
@ -3635,6 +3758,35 @@ public:
inline ObjList& groups()
{ return m_groups; }
/**
* Check if the contact is locally saved
* @param defVal Default value to return if parameter is invalid
* @return True if the contact is locally saved
*/
inline bool local(bool defVal = false) const
{ return m_params.getBoolValue("local",defVal); }
/**
* Set contact locally saved flag
* @param on The new value for locally saved flag
*/
inline void setLocal(bool on)
{ m_params.setParam("local",String::boolText(on)); }
/**
* Check if the contact is saved on server
* @param defVal Default value to return if parameter is invalid
* @return True if the contact is saved on server
*/
inline bool remote(bool defVal = false) const
{ return m_params.getBoolValue("remote",defVal); }
/**
* Set contact server saved flag
* @param on The new value for server saved flag
*/
inline void setRemote(bool on)
{ m_params.setParam("remote",String::boolText(on)); }
/**
* Set/reset the docked chat flag for non MucRoom contact
@ -3957,6 +4109,7 @@ public:
String m_name; // Contact's display name
String m_subscription; // Presence subscription state
NamedList m_params; // Optional contact extra params
protected:
/**