Added file sharing support.

git-svn-id: http://yate.null.ro/svn/yate/trunk@5483 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2013-04-23 11:34:13 +00:00
parent 32b5f99080
commit c7965f8986
28 changed files with 5104 additions and 362 deletions

View File

@ -22,9 +22,12 @@
#include "yatecbase.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#ifndef OUT_BUFFER_SIZE
#define OUT_BUFFER_SIZE 8192
#endif
using namespace TelEngine;
@ -55,6 +58,7 @@ public:
updateTableRow,
updateTableRows,
clearTable,
setBusy,
getText,
getCheck,
getSelect,
@ -324,6 +328,15 @@ const TokenDict ClientResource::s_statusName[] = {
{0,0}
};
// resource.notify capability names
const TokenDict ClientResource::s_resNotifyCaps[] = {
{"audio", ClientResource::CapAudio},
{"filetransfer", ClientResource::CapFileTransfer},
{"fileinfoshare", ClientResource::CapFileInfo},
{"resultsetmngt", ClientResource::CapRsm},
{0,0}
};
// MucRoomMember affiliations
const TokenDict MucRoomMember::s_affName[] = {
{"owner", MucRoomMember::Owner},
@ -388,15 +401,17 @@ static inline bool callLogicToggle(ClientLogic* logic, Window* wnd, const String
// Utility function used in Client::select()
// Output a debug message and calls a logic's select method
static inline bool callLogicSelect(ClientLogic* logic, Window* wnd, const String& name,
const String& item, const String& text)
const String& item, const String& text, const NamedList* items)
{
if (!logic)
return false;
DDebug(ClientDriver::self(),DebugAll,
"Logic(%s) select='%s' item='%s' in window (%p,%s) [%p]",
logic->toString().c_str(),name.c_str(),item.c_str(),
"Logic(%s) select='%s' item='%s' items=%p in window (%p,%s) [%p]",
logic->toString().c_str(),name.c_str(),item.c_str(),items,
wnd,wnd ? wnd->id().c_str() : "",logic);
return logic->select(wnd,name,item,text);
if (!items)
return logic->select(wnd,name,item,text);
return logic->select(wnd,name,*items);
}
// Utility function used to check for action/toggle/select preferences
@ -496,40 +511,37 @@ bool Window::related(const Window* wnd) const
bool Window::setParams(const NamedList& params)
{
bool ok = true;
unsigned int l = params.length();
for (unsigned int i = 0; i < l; i++) {
const NamedString* s = params.getParam(i);
if (s) {
String n(s->name());
if (n == YSTRING("title"))
title(*s);
if (n == YSTRING("context"))
context(*s);
else if (n.startSkip("show:",false) || n.startSkip("display:",false))
ok = setShow(n,s->toBoolean()) && ok;
else if (n.startSkip("active:",false))
ok = setActive(n,s->toBoolean()) && ok;
else if (n.startSkip("focus:",false))
ok = setFocus(n,s->toBoolean()) && ok;
else if (n.startSkip("check:",false))
ok = setCheck(n,s->toBoolean()) && ok;
else if (n.startSkip("select:",false))
ok = setSelect(n,*s) && ok;
else if (n.startSkip("image:",false))
ok = setImage(n,*s) && ok;
else if (n.startSkip("property:",false)) {
// Set property: object_name:property_name=value
int pos = n.find(':');
if (pos > 0)
ok = setProperty(n.substr(0,pos),n.substr(pos + 1),*s) && ok;
else
ok = false;
}
else if (n.find(':') < 0)
ok = setText(n,*s) && ok;
NamedIterator iter(params);
for (const NamedString* s = 0; 0 != (s = iter.get());) {
String n(s->name());
if (n == YSTRING("title"))
title(*s);
if (n == YSTRING("context"))
context(*s);
else if (n.startSkip("show:",false) || n.startSkip("display:",false))
ok = setShow(n,s->toBoolean()) && ok;
else if (n.startSkip("active:",false))
ok = setActive(n,s->toBoolean()) && ok;
else if (n.startSkip("focus:",false))
ok = setFocus(n,s->toBoolean()) && ok;
else if (n.startSkip("check:",false))
ok = setCheck(n,s->toBoolean()) && ok;
else if (n.startSkip("select:",false))
ok = setSelect(n,*s) && ok;
else if (n.startSkip("image:",false))
ok = setImage(n,*s) && ok;
else if (n.startSkip("property:",false)) {
// Set property: object_name:property_name=value
int pos = n.find(':');
if (pos > 0)
ok = setProperty(n.substr(0,pos),n.substr(pos + 1),*s) && ok;
else
ok = false;
ok = false;
}
else if (n.find(':') < 0)
ok = setText(n,*s) && ok;
else
ok = false;
}
return ok;
}
@ -837,6 +849,9 @@ void ClientThreadProxy::process()
case clearTable:
m_rval = client->clearTable(m_name,m_wnd,m_skip);
break;
case setBusy:
m_rval = client->setBusy(m_name,m_bool,m_wnd,m_skip);
break;
case getText:
m_rval = client->getText(m_name,*m_rtext,m_rbool ? *m_rbool : false,m_wnd,m_skip);
break;
@ -844,7 +859,10 @@ void ClientThreadProxy::process()
m_rval = client->getCheck(m_name,*m_rbool,m_wnd,m_skip);
break;
case getSelect:
m_rval = client->getSelect(m_name,*m_rtext,m_wnd,m_skip);
if (!m_params)
m_rval = client->getSelect(m_name,*m_rtext,m_wnd,m_skip);
else
m_rval = client->getSelect(m_name,*const_cast<NamedList*>(m_params),m_wnd,m_skip);
break;
case getOptions:
m_rval = client->getOptions(m_name,const_cast<NamedList*>(m_params),m_wnd,m_skip);
@ -1796,6 +1814,28 @@ bool Client::clearTable(const String& name, Window* wnd, Window* skip)
return ok;
}
// Show or hide control busy state
bool Client::setBusy(const String& name, bool on, Window* wnd, Window* skip)
{
if (!valid())
return false;
if (needProxy()) {
ClientThreadProxy proxy(ClientThreadProxy::setBusy,name,on,wnd,skip);
return proxy.execute();
}
if (wnd)
return wnd->setBusy(name,on);
++s_changing;
bool ok = false;
for (ObjList* o = m_windows.skipNull(); o; o = o->skipNext()) {
wnd = static_cast<Window*>(o->get());
if (wnd != skip)
ok = wnd->setBusy(name,on) || ok;
}
--s_changing;
return ok;
}
// function for obtaining the text from the "name" widget
bool Client::getText(const String& name, String& text, bool richText, Window* wnd, Window* skip)
{
@ -1856,6 +1896,25 @@ bool Client::getSelect(const String& name, String& item, Window* wnd, Window* sk
return false;
}
// Retrieve an element's multiple selection
bool Client::getSelect(const String& name, NamedList& items, Window* wnd, Window* skip)
{
if (!valid())
return false;
if (needProxy()) {
ClientThreadProxy proxy(ClientThreadProxy::getSelect,name,&items,wnd,skip);
return proxy.execute();
}
if (wnd)
return wnd->getSelect(name,items);
for (ObjList* l = m_windows.skipNull(); l; l = l->skipNext()) {
wnd = static_cast<Window*>(l->get());
if ((wnd != skip) && wnd->getSelect(name,items))
return true;
}
return false;
}
// Build a menu from a list of parameters.
bool Client::buildMenu(const NamedList& params, Window* wnd, Window* skip)
{
@ -2256,41 +2315,70 @@ bool Client::toggle(Window* wnd, const String& name, bool active)
return false;
}
// Handle selection changes (list selection changes, focus changes ...)
bool Client::select(Window* wnd, const String& name, const String& item, const String& text)
// Handle different select() methods
static bool handleSelect(ObjList& logics, Window* wnd, const String& name,
const String& item, const String& text, const NamedList* items)
{
static const String sect = "select";
XDebug(ClientDriver::self(),DebugAll,
"Select name='%s' item='%s' in window (%p,%s)",
name.c_str(),item.c_str(),wnd,wnd ? wnd->id().c_str() : "");
String substitute = name;
String handle;
bool only = false, prefer = false, ignore = false, bailout = false;
bool ok = false;
if (hasOverride(s_actions.getSection(sect),substitute,handle,only,prefer,ignore,bailout) &&
if (hasOverride(Client::s_actions.getSection(sect),substitute,handle,only,prefer,ignore,bailout) &&
(only || prefer)) {
ok = callLogicSelect(findLogic(handle),wnd,substitute,item,text);
ok = callLogicSelect(Client::findLogic(handle),wnd,substitute,item,text,items);
bailout = only || ok;
}
if (bailout)
return ok;
for(ObjList* o = s_logics.skipNull(); o; o = o->skipNext()) {
for(ObjList* o = logics.skipNull(); o; o = o->skipNext()) {
ClientLogic* logic = static_cast<ClientLogic*>(o->get());
if (ignore && handle == logic->toString())
continue;
if (callLogicSelect(logic,wnd,substitute,item,text))
if (callLogicSelect(logic,wnd,substitute,item,text,items))
return true;
}
// Not processed: enqueue event
Message* m = eventMessage("select",wnd,substitute);
m->addParam("item",item);
m->addParam("text",text,false);
Message* m = Client::eventMessage("select",wnd,substitute);
if (!items) {
m->addParam("item",item);
m->addParam("text",text,false);
}
else {
NamedIterator iter(*items);
String prefix = "item.";
int n = 0;
for (const NamedString* ns = 0; 0 != (ns = iter.get());) {
String pref = prefix;
pref << n++;
m->addParam(pref,ns->name());
if (*ns)
m->addParam(pref + ".text",*ns);
}
}
Engine::enqueue(m);
return false;
}
// Handle selection changes (list selection changes, focus changes ...)
bool Client::select(Window* wnd, const String& name, const String& item, const String& text)
{
XDebug(ClientDriver::self(),DebugAll,
"Select name='%s' item='%s' in window (%p,%s)",
name.c_str(),item.c_str(),wnd,wnd ? wnd->id().c_str() : "");
return handleSelect(s_logics,wnd,name,item,text,0);
}
// Handle 'select' with multiple items actions from user interface
bool Client::select(Window* wnd, const String& name, const NamedList& items)
{
XDebug(ClientDriver::self(),DebugAll,
"Select name='%s' items=%p in window (%p,%s)",
name.c_str(),&items,wnd,wnd ? wnd->id().c_str() : "");
return handleSelect(s_logics,wnd,name,String::empty(),String::empty(),&items);
}
// function for setting the current line
void Client::line(int newLine)
{
@ -3065,6 +3153,20 @@ void Client::plain2html(String& buf, bool spaceEol)
}
}
// Find a list parameter by its value
NamedString* Client::findParamByValue(NamedList& list, const String& value,
NamedString* skip)
{
NamedIterator iter(list);
for (const NamedString* ns = 0; 0 != (ns = iter.get());) {
if (skip && skip == ns)
continue;
if (*ns == value)
return (NamedString*)ns;
}
return 0;
}
static bool lookupFlag(const char* what, const TokenDict* dict, int& flags)
{
bool on = true;
@ -3177,6 +3279,18 @@ bool Client::removeLastNameInPath(String& dest, const String& path, char sep,
return ok;
}
// Add a formatted log line
bool Client::addToLogFormatted(const char* format, ...)
{
char buf[OUT_BUFFER_SIZE];
va_list va;
va_start(va,format);
::vsnprintf(buf,sizeof(buf) - 1,format,va);
va_end(va);
dbg_client_func(buf,-1);
return true;
}
// Build an 'ui.event' message
Message* Client::eventMessage(const String& event, Window* wnd, const char* name,
NamedList* params)
@ -3186,14 +3300,8 @@ Message* Client::eventMessage(const String& event, Window* wnd, const char* name
m->addParam("window",wnd->id());
m->addParam("event",event);
m->addParam("name",name,false);
if (params) {
unsigned int n = params->count();
for (unsigned int i = 0; i < n; i++) {
NamedString* p = params->getParam(i);
if (p)
m->addParam(p->name(),*p);
}
}
if (params)
m->copyParams(*params);
return m;
}
@ -4132,8 +4240,10 @@ void ClientAccount::setContact(ClientContact* contact)
m_contact->m_owner = 0;
TelEngine::destruct(m_contact);
m_contact = contact;
if (m_contact)
if (m_contact) {
m_contact->m_owner = this;
m_contact->setSubscription("both");
}
}
// Get this account's resource
@ -4809,7 +4919,7 @@ void ClientAccountList::removeAccount(const String& id)
ClientContact::ClientContact(ClientAccount* owner, const char* id, const char* name,
const char* uri)
: m_name(name ? name : id), m_params(""), m_owner(owner), m_online(false),
m_uri(uri), m_dockedChat(false)
m_uri(uri), m_dockedChat(false), m_share("")
{
m_dockedChat = Client::valid() && Client::self()->getBoolOpt(Client::OptDockedChat);
m_id = id ? id : uri;
@ -4817,6 +4927,7 @@ ClientContact::ClientContact(ClientAccount* owner, const char* id, const char* n
owner,m_id.c_str(),m_uri.c_str(),this);
if (m_owner)
m_owner->appendContact(this);
updateShare();
// Generate chat window name
buildIdHash(m_chatWndName,s_chatPrefix);
}
@ -4825,7 +4936,7 @@ ClientContact::ClientContact(ClientAccount* owner, const char* id, const char* n
ClientContact::ClientContact(ClientAccount* owner, const NamedList& params, const char* id,
const char* uri)
: m_name(params.getValue(YSTRING("name"),params)), m_params(""),
m_owner(owner), m_online(false), m_uri(uri), m_dockedChat(false)
m_owner(owner), m_online(false), m_uri(uri), m_dockedChat(false), m_share("")
{
m_dockedChat = Client::valid() && Client::self()->getBoolOpt(Client::OptDockedChat);
m_id = id ? id : params.c_str();
@ -4833,13 +4944,15 @@ ClientContact::ClientContact(ClientAccount* owner, const NamedList& params, cons
owner,m_id.c_str(),m_uri.c_str(),this);
if (m_owner)
m_owner->appendContact(this);
updateShare();
// Generate chat window name
buildIdHash(m_chatWndName,s_chatPrefix);
}
// Constructor. Append itself to the owner's list
ClientContact::ClientContact(ClientAccount* owner, const char* id, bool mucRoom)
: m_params(""), 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),
m_share("")
{
if (m_owner)
m_owner->appendContact(this,mucRoom);
@ -4847,6 +4960,23 @@ ClientContact::ClientContact(ClientAccount* owner, const char* id, bool mucRoom)
m_dockedChat = Client::valid() && Client::self()->getBoolOpt(Client::OptDockedChat);
buildIdHash(m_chatWndName,s_chatPrefix);
}
updateShare();
}
// Set contact's subscription
bool ClientContact::setSubscription(const String& value)
{
if (m_subscription == value)
return false;
m_subscription = value;
m_sub = 0;
if (m_subscription == YSTRING("both"))
m_sub = SubFrom | SubTo;
else if (m_subscription == YSTRING("from"))
m_sub = SubFrom;
else if (m_subscription == YSTRING("to"))
m_sub = SubTo;
return true;
}
// Check if this contact has a chat widget (window or docked item)
@ -5219,7 +5349,7 @@ ClientResource* ClientContact::findAudioResource(bool ref)
Lock lock(m_owner);
ObjList* o = m_resources.skipNull();
for (; o; o = o->skipNext())
if ((static_cast<ClientResource*>(o->get()))->m_audio)
if ((static_cast<ClientResource*>(o->get()))->caps().flag(ClientResource::CapAudio))
break;
if (!o)
return 0;
@ -5233,7 +5363,7 @@ ClientResource* ClientContact::findFileTransferResource(bool ref)
Lock lock(m_owner);
ObjList* o = m_resources.skipNull();
for (; o; o = o->skipNext())
if ((static_cast<ClientResource*>(o->get()))->m_fileTransfer)
if ((static_cast<ClientResource*>(o->get()))->caps().flag(ClientResource::CapFileTransfer))
break;
if (!o)
return 0;
@ -5294,6 +5424,156 @@ bool ClientContact::removeResource(const String& id)
return true;
}
// (re)load shared list
void ClientContact::updateShare()
{
m_share.clearParams();
if (!(account() && uri()))
return;
NamedList* sect = account()->m_cfg.getSection("share " + uri());
if (!sect)
return;
for (int n = 1; true; n++) {
String s(n);
NamedString* ns = sect->getParam(s);
if (!ns)
break;
if (!*ns)
continue;
setShareDir((*sect)[s + ".name"],*ns,false);
}
}
// Save share list
void ClientContact::saveShare()
{
if (!(account() && uri()))
return;
String tmp;
tmp << "share " << uri();
NamedList* sect = account()->m_cfg.getSection(tmp);
bool changed = false;
if (haveShare()) {
if (!sect)
sect = account()->m_cfg.createSection(tmp);
sect->clearParams();
NamedIterator iter(m_share);
int n = 1;
for (const NamedString* ns = 0; 0 != (ns = iter.get());) {
String s(n++);
sect->addParam(s,ns->name());
if (*ns && *ns != ns->name())
sect->addParam(s + ".name",*ns);
}
changed = true;
}
else if (sect) {
changed = true;
account()->m_cfg.clearSection(tmp);
}
if (!changed)
return;
if (account()->m_cfg.save())
return;
int code = Thread::lastError();
String s;
Thread::errorString(s,code);
Debug(ClientDriver::self(),DebugNote,
"Account(%s) contact='%s' failed to save shared: %d %s [%p]",
m_owner ? m_owner->toString().c_str() : "",m_uri.c_str(),code,s.c_str(),this);
}
// Clear share list
void ClientContact::clearShare()
{
if (!haveShare())
return;
m_share.clearParams();
saveShare();
}
// Set a share directory
bool ClientContact::setShareDir(const String& shareName, const String& dirPath, bool save)
{
String path;
if (!Client::removeEndsWithPathSep(path,dirPath))
return false;
String name = shareName;
if (!name)
Client::getLastNameInPath(name,path);
NamedString* ns = m_share.getParam(path);
NamedString* other = Client::findParamByValue(m_share,name,ns);
if (other)
return false;
bool changed = false;
if (ns) {
if (*ns != name) {
changed = true;
*ns = name;
}
}
else {
changed = true;
m_share.addParam(path,name);
}
if (changed && save)
saveShare();
return changed;
}
// Remove a shared item
bool ClientContact::removeShare(const String& name, bool save)
{
NamedString* ns = m_share.getParam(name);
if (!ns)
return false;
m_share.clearParam(ns);
if (save)
saveShare();
return true;
}
// Check if the list of shared contains something
bool ClientContact::haveShared() const
{
for (ObjList* o = m_shared.skipNull(); o; o = o->skipNext()) {
ClientDir* d = static_cast<ClientDir*>(o->get());
if (d->children().skipNull())
return true;
}
return false;
}
// Retrieve shared data for a given resource
ClientDir* ClientContact::getShared(const String& name, bool create)
{
if (!name)
return 0;
ObjList* o = m_shared.find(name);
if (!o && create)
o = m_shared.append(new ClientDir(name));
return o ? static_cast<ClientDir*>(o->get()) : 0;
}
// Remove shared data
bool ClientContact::removeShared(const String& name, ClientDir** removed)
{
bool chg = false;
if (name) {
GenObject* gen = m_shared.remove(name,false);
chg = (gen != 0);
if (removed)
*removed = static_cast<ClientDir*>(gen);
else
TelEngine::destruct(gen);
}
else {
chg = (0 != m_shared.skipNull());
m_shared.clear();
}
return chg;
}
// Split a contact instance id in account/contact/instance parts
void ClientContact::splitContactInstanceId(const String& src, String& account,
String& contact, String* instance)
@ -5821,6 +6101,136 @@ void ClientSound::doStop()
}
//
// ClientDir
//
// Recursively check if all (sub)directores were updated
bool ClientDir::treeUpdated() const
{
if (!m_updated)
return false;
for (ObjList* o = m_children.skipNull(); o; o = o->skipNext()) {
ClientFileItem* it = static_cast<ClientFileItem*>(o->get());
ClientDir* dir = it->directory();
if (dir && !dir->treeUpdated())
return false;
}
return true;
}
// Build and add a sub-directory if not have one already
ClientDir* ClientDir::addDir(const String& name)
{
if (!name)
return 0;
ClientFileItem* it = findChild(name);
if (it) {
if (it->directory())
return it->directory();
}
ClientDir* d = new ClientDir(name);
addChild(d);
return d;
}
// Build sub directories from path
ClientDir* ClientDir::addDirPath(const String& path, const char* sep)
{
if (!path)
return 0;
if (TelEngine::null(sep))
return addDir(path);
int pos = path.find(sep);
if (pos < 0)
return addDir(path);
String rest = path.substr(pos + 1);
String name = path.substr(0,pos);
ClientDir* d = this;
if (name)
d = addDir(name);
if (!d)
return 0;
return rest ? d->addDirPath(rest) : d;
}
// Add a copy of known children types
void ClientDir::copyChildren(const ObjList& list)
{
for (ObjList* o = list.skipNull(); o; o = o->skipNext()) {
ClientFileItem* item = static_cast<ClientFileItem*>(o->get());
if (item->file())
addChild(new ClientFile(*item->file()));
else if (item->directory())
addChild(new ClientDir(*item->directory()));
}
}
// Add a list of children, consume the objects
void ClientDir::addChildren(ObjList& list)
{
for (ObjList* o = list.skipNull(); o; o = o->skipNull()) {
ClientFileItem* item = static_cast<ClientFileItem*>(o->remove(false));
addChild(item);
}
}
// Add/replace an item
bool ClientDir::addChild(ClientFileItem* item)
{
if (!item)
return false;
ObjList* last = 0;
for (ObjList* o = m_children.skipNull(); o; o = o->skipNext()) {
ClientFileItem* it = static_cast<ClientFileItem*>(o->get());
if (it == item)
return true;
if (it->name() == item->name()) {
o->remove();
o->append(item);
return true;
}
ObjList* tmp = o->skipNext();
if (!tmp) {
last = o;
break;
}
o = tmp;
}
if (last)
last->append(item);
else
m_children.append(item);
return true;
}
// Find a child by path
ClientFileItem* ClientDir::findChild(const String& path, const char* sep)
{
if (!path)
return 0;
if (TelEngine::null(sep))
return findChildName(path);
int pos = path.find(sep);
if (pos < 0)
return findChildName(path);
String rest = path.substr(pos + 1);
String name = path.substr(0,pos);
if (!name)
return findChild(rest,sep);
ClientFileItem* ch = findChildName(name);
if (!ch)
return 0;
// Nothing more in the path, return found child
if (!name)
return ch;
// Found child can't contain children: error
ClientDir* d = ch->directory();
if (d)
return d->findChild(rest,sep);
return 0;
}
//
// NamedInt
//

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
<ui version="4.0" >
<class>Form</class>
<widget class="QWidget" name="Form" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>322</width>
<height>265</height>
</rect>
</property>
<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="QHBoxLayout" >
<item>
<widget class="QLabel" name="gif" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
<property name="textInteractionFlags" >
<set>Qt::NoTextInteraction</set>
</property>
<property name="_yate_movie_file" stdset="0" >
<string>waiting_32.gif</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -79,6 +79,9 @@ QToolButton:hover {
QToolButton:pressed {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #eeeeee);
}
QToolButton:disabled {
background: #eeeeee;
}
</string>
</property>
<property name="iconSize" >
@ -113,6 +116,195 @@ QToolButton:pressed {
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="send_file_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="styleSheet" >
<string>QToolButton {
border: 1px solid #00b4ff;
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #eeeeee);
}
QToolButton:hover {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #eeeeee, stop: 1 #ffffff);
}
QToolButton:pressed {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #eeeeee);
}
QToolButton:disabled {
background: #eeeeee;
}
</string>
</property>
<property name="iconSize" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
<property name="autoRaise" >
<bool>true</bool>
</property>
<property name="_yate_identity" stdset="0" >
<string>send_file</string>
</property>
<property name="_yate_setaction" stdset="0" >
<string>chat_send_file</string>
</property>
<property name="_yate_noautoconnect" stdset="0" >
<bool>true</bool>
</property>
<property name="_yate_normal_icon" stdset="0" >
<string>sendfile_20.png</string>
</property>
<property name="_yate_pressed_icon" stdset="0" >
<string>sendfile_pressed_20.png</string>
</property>
<property name="_yate_hover_icon" stdset="0" >
<string>sendfile_hover_20.png</string>
</property>
<property name="_yate_filterevents" stdset="0" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="share_file_btn" >
<property name="enabled" >
<bool>true</bool>
</property>
<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="styleSheet" >
<string>QToolButton {
border: 1px solid #00b4ff;
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #eeeeee);
}
QToolButton:hover {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #eeeeee, stop: 1 #ffffff);
}
QToolButton:pressed {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #eeeeee);
}
QToolButton:disabled {
background: #eeeeee;
}
</string>
</property>
<property name="iconSize" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
<property name="autoRaise" >
<bool>true</bool>
</property>
<property name="_yate_identity" stdset="0" >
<string>share_file</string>
</property>
<property name="_yate_setaction" stdset="0" >
<string>chat_share_file</string>
</property>
<property name="_yate_noautoconnect" stdset="0" >
<bool>true</bool>
</property>
<property name="_yate_normal_icon" stdset="0" >
<string>sharefile_none_20.png</string>
</property>
<property name="_yate_pressed_icon" stdset="0" >
<string>sharefile_none_pressed_20.png</string>
</property>
<property name="_yate_hover_icon" stdset="0" >
<string>sharefile_none_hover_20.png</string>
</property>
<property name="_yate_filterevents" stdset="0" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="shared_file_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="styleSheet" >
<string>QToolButton {
border: 1px solid #00b4ff;
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #eeeeee);
}
QToolButton:hover {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #eeeeee, stop: 1 #ffffff);
}
QToolButton:pressed {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #eeeeee);
}
QToolButton:disabled {
background: #eeeeee;
}
</string>
</property>
<property name="iconSize" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
<property name="autoRaise" >
<bool>true</bool>
</property>
<property name="_yate_identity" stdset="0" >
<string>shared_file</string>
</property>
<property name="_yate_setaction" stdset="0" >
<string>chat_shared_file</string>
</property>
<property name="_yate_noautoconnect" stdset="0" >
<bool>true</bool>
</property>
<property name="_yate_normal_icon" stdset="0" >
<string>sharedfile_20.png</string>
</property>
<property name="_yate_pressed_icon" stdset="0" >
<string>sharedfile_pressed_20.png</string>
</property>
<property name="_yate_hover_icon" stdset="0" >
<string>sharedfile_hover_20.png</string>
</property>
<property name="_yate_filterevents" stdset="0" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="name" >
<property name="sizePolicy" >
@ -550,6 +742,39 @@ QToolButton:pressed {
<string>room_invite_contacts</string>
</property>
</action>
<action name="chat_send_file" >
<property name="icon" >
<iconset>sendfile_20.png</iconset>
</property>
<property name="text" >
<string>Send file</string>
</property>
<property name="_yate_identity" stdset="0" >
<string>send_file</string>
</property>
</action>
<action name="chat_share_file" >
<property name="icon" >
<iconset>sharefile_none_20.png</iconset>
</property>
<property name="text" >
<string>Share Files</string>
</property>
<property name="_yate_identity" stdset="0" >
<string>share_file</string>
</property>
</action>
<action name="chat_shared_file" >
<property name="icon" >
<iconset>sharedfile_20.png</iconset>
</property>
<property name="text" >
<string>Shared files</string>
</property>
<property name="_yate_identity" stdset="0" >
<string>shared_file</string>
</property>
</action>
</widget>
<resources/>
<connections/>

View File

@ -0,0 +1,332 @@
<ui version="4.0" >
<class>conctactfs</class>
<widget class="QWidget" name="conctactfs" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>387</width>
<height>373</height>
</rect>
</property>
<property name="windowIcon" >
<iconset>sharefile_title.png</iconset>
</property>
<property name="_yate_window" stdset="0" >
<bool>true</bool>
</property>
<property name="_yate_destroyonclose" stdset="0" >
<bool>true</bool>
</property>
<property name="_yate_destroyonhide" stdset="0" >
<bool>true</bool>
</property>
<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>6</number>
</property>
<property name="leftMargin" >
<number>6</number>
</property>
<property name="topMargin" >
<number>6</number>
</property>
<property name="rightMargin" >
<number>6</number>
</property>
<property name="bottomMargin" >
<number>6</number>
</property>
<item>
<widget class="QFrame" name="frame_list" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet" >
<string>QFrame#frame_list {
border: 1px solid #717fa0;
}
</string>
</property>
<property name="_yate_uiwidget" stdset="0" >
<bool>true</bool>
</property>
<property name="_yate_uiwidget_name" stdset="0" >
<string>share_file_list</string>
</property>
<property name="_yate_uiwidget_class" stdset="0" >
<string>QtCustomTree</string>
</property>
<property name="_yate_uiwidget_params" stdset="0" >
<stringlist>
<string>property:_yate_save_props=_yate_col_widths</string>
<string>_yate_selection_mode=extended</string>
<string>_yate_edit_triggers=all,!currentchanged,!anykeypress</string>
<string>_yate_set_currentcolumn=name</string>
<string>property:tabKeyNavigation=false</string>
<string>property:sortingEnabled=false</string>
<string>property:allColumnsShowFocus=true</string>
<string>property:_yate_horizontalheader=true</string>
<string>property:_yate_notifyonenterpressed=true</string>
<string>property:_yate_notifyitemchanged=true</string>
<string>property:_yate_itemheight=24</string>
<string>property:_yate_itemeditable=true</string>
<string>property:_yate_itemacceptdrop=:always</string>
<string>property:_yate_itemacceptdroponempty=always</string>
<string>griddraw_right_color=#e3e6e9</string>
<string>griddraw_bottom_color=#a9c2c2</string>
<string>columns=Name,Path</string>
<string>columns.width=140</string>
<string>itemdelegate.1=</string>
<string>itemdelegate.1.editable_cols=name</string>
<string>itemdelegate.1.noroles=true</string>
<string>itemdelegate.1.drawfocus=false</string>
<string>_yate_set_draganddrop=drop</string>
<string>_yate_accept_drop_schemes=file</string>
<string>_yate_accept_drop_dir=true</string>
<string>_yate_accept_drop_file=false</string>
</stringlist>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>2</number>
</property>
<item>
<widget class="QLabel" name="account_image" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="toolTip" >
<string>Account</string>
</property>
<property name="pixmap" >
<pixmap>user.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="account" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>26</height>
</size>
</property>
<property name="toolTip" >
<string>Account</string>
</property>
<property name="indent" >
<number>5</number>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" >
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="file_share_new" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>26</height>
</size>
</property>
<property name="toolTip" >
<string>Add a share directory</string>
</property>
<property name="text" >
<string>New</string>
</property>
<property name="icon" >
<iconset>add.png</iconset>
</property>
<property name="toolButtonStyle" >
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="_yate_normal_icon" stdset="0" >
<string>add.png</string>
</property>
<property name="_yate_pressed_icon" stdset="0" >
<string>add_pressed.png</string>
</property>
<property name="_yate_hover_icon" stdset="0" >
<string>add_hover.png</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="file_share_del" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>26</height>
</size>
</property>
<property name="toolTip" >
<string>Delete selected shared item(s)</string>
</property>
<property name="text" >
<string>Delete</string>
</property>
<property name="icon" >
<iconset>delete.png</iconset>
</property>
<property name="toolButtonStyle" >
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="_yate_normal_icon" stdset="0" >
<string>delete.png</string>
</property>
<property name="_yate_pressed_icon" stdset="0" >
<string>delete_pressed.png</string>
</property>
<property name="_yate_hover_icon" stdset="0" >
<string>delete_hover.png</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="file_share_rename" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>26</height>
</size>
</property>
<property name="toolTip" >
<string>Edit the selected shared item</string>
</property>
<property name="text" >
<string>Rename</string>
</property>
<property name="icon" >
<iconset>edit.png</iconset>
</property>
<property name="toolButtonStyle" >
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="_yate_normal_icon" stdset="0" >
<string>edit.png</string>
</property>
<property name="_yate_pressed_icon" stdset="0" >
<string>edit_pressed.png</string>
</property>
<property name="_yate_hover_icon" stdset="0" >
<string>edit_hover.png</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,456 @@
<ui version="4.0" >
<class>conctactfs</class>
<widget class="QWidget" name="conctactfs" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>656</width>
<height>471</height>
</rect>
</property>
<property name="windowIcon" >
<iconset>sharedfile_title.png</iconset>
</property>
<property name="_yate_window" stdset="0" >
<bool>true</bool>
</property>
<property name="_yate_destroyonclose" stdset="0" >
<bool>true</bool>
</property>
<property name="_yate_destroyonhide" stdset="0" >
<bool>true</bool>
</property>
<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="QHBoxLayout" >
<property name="spacing" >
<number>0</number>
</property>
<property name="leftMargin" >
<number>6</number>
</property>
<property name="topMargin" >
<number>6</number>
</property>
<property name="rightMargin" >
<number>6</number>
</property>
<item>
<widget class="QSplitter" name="splitter" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="handleWidth" >
<number>8</number>
</property>
<property name="childrenCollapsible" >
<bool>false</bool>
</property>
<widget class="QFrame" name="frame_local" >
<property name="frameShape" >
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Raised</enum>
</property>
<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>
<widget class="QSplitter" name="splitter_2" >
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="opaqueResize" >
<bool>false</bool>
</property>
<property name="childrenCollapsible" >
<bool>false</bool>
</property>
<widget class="QFrame" name="frame_dirs" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>100</width>
<height>16</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet" >
<string>QFrame#frame_dirs {
border: 1px solid #717fa0;
}
</string>
</property>
<property name="_yate_uiwidget" stdset="0" >
<bool>true</bool>
</property>
<property name="_yate_uiwidget_name" stdset="0" >
<string>shared_dir_list</string>
</property>
<property name="_yate_uiwidget_class" stdset="0" >
<string>FileListTree</string>
</property>
<property name="_yate_uiwidget_params" stdset="0" >
<stringlist>
<string>_yate_set_draganddrop=drag</string>
<string>_yate_drag_url_template=yatedownload:${path}</string>
<string>_yate_drag_url_queryparams=account,contact,instance</string>
<string>_yate_busywidget=busy.ui</string>
<string>property:tabKeyNavigation=false</string>
<string>property:sortingEnabled=false</string>
<string>property:allColumnsShowFocus=true</string>
<string>property:rootIsDecorated=true</string>
<string>property:indentation=16</string>
<string>property:_yate_horizontalheader=false</string>
<string>property:_yate_notifyonenterpressed=true</string>
<string>property:_yate_notifyitemchanged=true</string>
<string>columns=Name</string>
<string>filelist_default_itemheight=false</string>
</stringlist>
</property>
</widget>
<widget class="QFrame" name="frame_content" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>100</width>
<height>16</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet" >
<string>QFrame#frame_content {
border: 1px solid #717fa0;
}
</string>
</property>
<property name="_yate_uiwidget" stdset="0" >
<bool>true</bool>
</property>
<property name="_yate_uiwidget_name" stdset="0" >
<string>shared_dir_content</string>
</property>
<property name="_yate_uiwidget_class" stdset="0" >
<string>FileListTree</string>
</property>
<property name="_yate_uiwidget_params" stdset="0" >
<stringlist>
<string>_yate_selection_mode=extended</string>
<string>_yate_set_draganddrop=drag</string>
<string>_yate_drag_url_template=yatedownload:${path}</string>
<string>_yate_drag_url_queryparams=account,contact,instance</string>
<string>_yate_busywidget=busy.ui</string>
<string>property:tabKeyNavigation=false</string>
<string>property:sortingEnabled=false</string>
<string>property:allColumnsShowFocus=true</string>
<string>property:_yate_horizontalheader=false</string>
<string>property:_yate_notifyonenterpressed=true</string>
<string>property:_yate_notifyitemchanged=true</string>
<string>_griddraw_right_color=#e3e6e9</string>
<string>_griddraw_bottom_color=#a9c2c2</string>
<string>columns=Name</string>
<string>itemdelegate.1=QtHtmlItemDelegate</string>
<string>itemdelegate.1.drawfocus=false</string>
<string>filelist_default_itemstyle=true</string>
<string>filelist_default_itemheight=true</string>
</stringlist>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QFrame" name="frame_remote" >
<property name="frameShape" >
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Raised</enum>
</property>
<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>
<widget class="QFrame" name="frame_local_fs" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>140</width>
<height>16</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet" >
<string>QFrame#frame_local_fs {
border: 1px solid black;
}
</string>
</property>
<property name="_yate_uiwidget" stdset="0" >
<bool>true</bool>
</property>
<property name="_yate_uiwidget_name" stdset="0" >
<string>local_fs</string>
</property>
<property name="_yate_uiwidget_class" stdset="0" >
<string>FileListTree</string>
</property>
<property name="_yate_uiwidget_params" stdset="0" >
<stringlist>
<string>_yate_selection_mode=extended</string>
<string>_yate_busywidget=busy.ui</string>
<string>_yate_busywidget_delay=500</string>
<string>_yate_set_draganddrop=drop</string>
<string>_yate_accept_drop_schemes=yatedownload</string>
<string>property:tabKeyNavigation=false</string>
<string>property:sortingEnabled=false</string>
<string>property:allColumnsShowFocus=true</string>
<string>property:_yate_horizontalheader=false</string>
<string>property:_yate_notifyonenterpressed=true</string>
<string>property:_yate_notifyitemchanged=true</string>
<string>property:_yate_itemacceptdrop=drive:always</string>
<string>property:_yate_itemacceptdrop=dir:always</string>
<string>property:_yate_itemacceptdrop=file:always</string>
<string>_griddraw_right_color=#e3e6e9</string>
<string>_griddraw_bottom_color=#a9c2c2</string>
<string>columns=Name</string>
<string>itemdelegate.1=QtHtmlItemDelegate</string>
<string>itemdelegate.1.drawfocus=false</string>
<string>itemdelegate.1.noimagerole=true</string>
<string>filelist_default_itemstyle=true</string>
<string>filelist_default_itemheight=true</string>
<string>filelist_filesystemlist=true</string>
<string>filelist_filesystemlist_name_column=name</string>
<string>filelist_filesystemlist_autochangedir=true</string>
<string>filelist_filesystemlist_listfiles=true</string>
<string>filelist_filesystemlist_listonfailure=upthenhome</string>
<string>filelist_filesystemlist_showicons=false</string>
<string>filelist_filesystemlist_startpath=root</string>
<string>_yate_accept_drop_dir=true</string>
<string>_yate_accept_drop_file=false</string>
</stringlist>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="leftMargin" >
<number>6</number>
</property>
<property name="topMargin" >
<number>6</number>
</property>
<property name="rightMargin" >
<number>6</number>
</property>
<property name="bottomMargin" >
<number>6</number>
</property>
<item>
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>2</number>
</property>
<item>
<widget class="QLabel" name="account_image" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="toolTip" >
<string>Account</string>
</property>
<property name="pixmap" >
<pixmap>user.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="account" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>26</height>
</size>
</property>
<property name="toolTip" >
<string>Account</string>
</property>
<property name="indent" >
<number>5</number>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" >
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="button_hide" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>26</height>
</size>
</property>
<property name="text" >
<string>Close</string>
</property>
<property name="icon" >
<iconset>cancel.png</iconset>
</property>
<property name="toolButtonStyle" >
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="_yate_normal_icon" stdset="0" >
<string>cancel.png</string>
</property>
<property name="_yate_pressed_icon" stdset="0" >
<string>cancel_pressed.png</string>
</property>
<property name="_yate_hover_icon" stdset="0" >
<string>cancel_hover.png</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -121,6 +121,16 @@ enabled=no
save=false
description=contactinfo.ui
[contactfs]
enabled=no
save=false
description=contactfs.ui
[contactfsd]
enabled=no
save=false
description=contactfsd.ui
[messages_header]
enabled=no
description=messages_header.ui
@ -149,3 +159,7 @@ description=fileprogress_item.ui
enabled=yes
visible=false
description=archive.ui
[busy]
enabled=no
description=busy.ui

View File

@ -121,7 +121,7 @@
<property name="title" >
<string>&amp;Friends</string>
</property>
<property name="_yate_menuNoCopy" stdset="0">
<property name="_yate_menuNoCopy" stdset="0" >
<bool>true</bool>
</property>
<widget class="QMenu" name="menuSubscription" >
@ -138,6 +138,8 @@
<addaction name="chatcontact_chat" />
<addaction name="chatcontact_call" />
<addaction name="send_file" />
<addaction name="share_file" />
<addaction name="shared_file" />
<addaction name="chatcontact_showlog" />
<addaction name="chatcontact_info" />
<addaction name="chatcontact_edit" />
@ -263,7 +265,6 @@
<string>property:_yate_horizontalheader=false</string>
<string>property:itemsExpandable=true</string>
<string>property:autoExpand=true</string>
<string>property:rootIsDecorated=false</string>
<string>property:allColumnsShowFocus=false</string>
<string>property:indentation=0</string>
<string>property:_yate_nogroup_caption=Not set</string>
@ -287,6 +288,18 @@
<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>property:_yate_itemmargins=contact:20</string>
<string>property:_yate_itemmargins=chatroom:20</string>
<string>property:_yate_itempaintbutton=contact:share_file</string>
<string>property:_yate_itempaintbuttonparam=contact:share_file:_yate_size:20</string>
<string>property:_yate_itempaintbuttonparam=contact:share_file:_yate_iconsize:20</string>
<string>property:_yate_itempaintbuttonparam=contact:share_file:_yate_normal_icon:sharefile_20.png</string>
<string>property:_yate_itempaintbuttonparam=contact:share_file:_yate_pressed_icon:sharefile_pressed_20.png</string>
<string>property:_yate_itempaintbuttonparam=contact:share_file:_yate_hover_icon:sharefile_hover_20.png</string>
<string>property:_yate_itempaintbutton=contact:shared_file</string>
<string>property:_yate_itempaintbuttonparam=contact:shared_file:_yate_size:20</string>
<string>property:_yate_itempaintbuttonparam=contact:shared_file:_yate_iconsize:20</string>
<string>property:_yate_itempaintbuttonparam=contact:shared_file:_yate_normal_icon:sharedfile_20.png</string>
<string>property:_yate_itempaintbuttonparam=contact:shared_file:_yate_pressed_icon:sharedfile_pressed_20.png</string>
<string>property:_yate_itempaintbuttonparam=contact:shared_file:_yate_hover_icon:sharedfile_hover_20.png</string>
</stringlist>
</property>
</widget>
@ -1112,7 +1125,7 @@ border-bottom: 1px solid #717fa0;
<property name="dynamicActionEnterFilter" stdset="0" >
<bool>true</bool>
</property>
<property name="_yate_textchangednotify" stdset="0">
<property name="_yate_textchangednotify" stdset="0" >
<bool>true</bool>
</property>
</widget>
@ -3058,7 +3071,7 @@ QTextEdit {
<property name="text" >
<string>Show notifications</string>
</property>
<property name="_yate_menuNoCopy" stdset="0">
<property name="_yate_menuNoCopy" stdset="0" >
<bool>true</bool>
</property>
</action>
@ -3149,6 +3162,22 @@ QTextEdit {
<string>Add chat room</string>
</property>
</action>
<action name="share_file" >
<property name="icon" >
<iconset>sharefile_menu.png</iconset>
</property>
<property name="text" >
<string>Share Files</string>
</property>
</action>
<action name="shared_file" >
<property name="icon" >
<iconset>sharedfile_menu.png</iconset>
</property>
<property name="text" >
<string>Shared Files</string>
</property>
</action>
</widget>
<resources/>
<connections/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 B

View File

@ -262,7 +262,6 @@ QTreeWidget {
selection-background-color: lightblue;
selection-color: black;
}
QTreeView::branch { background:#ffffff; }
/* QTableWidget */

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -78,6 +78,7 @@ Source: "Release\yate-qt4.exe"; DestDir: "{app}"; Flags: replacesameversion; Com
Source: "Runtimes\qtcore4.dll"; DestDir: "{app}"; Components: client\qt\run
Source: "Runtimes\qtgui4.dll"; DestDir: "{app}"; Components: client\qt\run
Source: "Runtimes\qtxml4.dll"; DestDir: "{app}"; Components: client\qt\run
Source: "Runtimes\imageformats\qgif4.dll"; DestDir: "{app}\imageformats"; Components: client\qt\run
Source: "Release\yate-service.exe"; DestDir: "{app}"; Flags: replacesameversion; Components: server
Source: "Release\yate-console.exe"; DestDir: "{app}"; Flags: replacesameversion; Components: debug
@ -191,6 +192,7 @@ Source: "..\conf.d\providers.conf.default"; DestName: "providers.conf"; DestDir:
Source: "..\share\skins\default\qt4client.rc"; DestDir: "{app}\share\skins\default"; Components: client\qt
Source: "..\share\skins\default\*.ui"; DestDir: "{app}\share\skins\default"; Components: client\qt
Source: "..\share\skins\default\*.png"; DestDir: "{app}\share\skins\default"; Components: client
Source: "..\share\skins\default\*.gif"; DestDir: "{app}\share\skins\default"; Components: client
Source: "..\share\skins\default\*.css"; DestDir: "{app}\share\skins\default"; Components: client
Source: "..\conf.d\yate-qt4.conf.default"; DestName: "yate-qt4.conf"; DestDir: "{app}\conf.d"; Components: client\qt; Flags: skipifsourcedoesntexist

View File

@ -36,6 +36,7 @@
*/
namespace TelEngine {
class Flags32; // Keeps a 32bit length flag mask
class NamedInt; // A named integer value
class Window; // A generic window
class UIWidget; // A custom widget
@ -54,14 +55,117 @@ class MucRoomMember; // A MUC room member
class MucRoom; // An account's MUC room contact
class DurationUpdate; // Class used to update UI durations
class ClientSound; // A sound file
class ClientFileItem; // Base class for file/dir items
class ClientDir; // A directory
class ClientFile; // A file
/**
* This class keeps a 32bit length flag mask
* @short A 32 bit length list of flags
*/
class YATE_API Flags32
{
public:
/**
* Constructor
*/
inline Flags32()
: m_flags(0)
{}
/**
* Constructor
* @param value Flags value
*/
inline Flags32(u_int32_t value)
: m_flags(value)
{}
/**
* Retrieve flags value
* @return The flags
*/
inline u_int32_t flags() const
{ return m_flags; }
/**
* Set flags
* @param mask Flag(s) to set
*/
inline void set(u_int32_t mask)
{ m_flags = m_flags | mask; }
/**
* Reset flags
* @param mask Flag(s) to reset
*/
inline void reset(u_int32_t mask)
{ m_flags = m_flags & ~mask; }
/**
* Check if a mask of flags is set
* @param mask Flag(s) to check
* @return The flags of mask which are set, 0 if no mask flag is set
*/
inline u_int32_t flag(u_int32_t mask) const
{ return (m_flags & mask); }
/**
* Set or reset flags
* @param mask Flag(s)
* @param on True to set, false to reset
*/
inline void changeFlag(u_int32_t mask, bool on) {
if (on)
set(mask);
else
reset(mask);
}
/**
* Set or reset flags, check if changed
* @param mask Flag(s)
* @param on True to set, false to reset
* @return True if any flag contained in mask changed
*/
inline bool changeFlagCheck(u_int32_t mask, bool ok) {
if ((0 != flag(mask)) == ok)
return false;
changeFlag(mask,ok);
return true;
}
/**
* Change flags
* @param value New flags value
*/
inline void change(u_int32_t value)
{ m_flags = value; }
/**
* Conversion to u_int32_t operator
*/
inline operator u_int32_t() const
{ return m_flags; }
/**
* Asignement from int operator
*/
inline const Flags32& operator=(int value)
{ m_flags = value; return *this; }
protected:
u_int32_t m_flags;
};
/**
* This class holds a name integer value
* @short A named integer value
*/
class YATE_API NamedInt: public String
{
YCLASS(NamedInt,String)
public:
/**
* Constructor
@ -150,6 +254,7 @@ private:
*/
class YATE_API Window : public GenObject
{
YCLASS(Window,GenObject)
friend class Client;
YNOCOPY(Window); // no automatic copies please
public:
@ -395,6 +500,14 @@ public:
*/
virtual bool clearTable(const String& name);
/**
* Show or hide control busy state
* @param name Name of the element
* @param on True to show, false to hide
* @return True if all the operations were successfull
*/
virtual bool setBusy(const String& name, bool on) = 0;
/**
* Get an element's text
* @param name Name of the element
@ -420,6 +533,14 @@ public:
*/
virtual bool getSelect(const String& name, String& item) = 0;
/**
* Retrieve an element's multiple selection
* @param name Name of the element
* @param items List to be to filled with selection's contents
* @return True if the operation was successfull
*/
virtual bool getSelect(const String& name, NamedList& items) = 0;
/**
* Build a menu from a list of parameters.
* See Client::buildMenu() for more info
@ -634,6 +755,7 @@ private:
class YATE_API UIWidget : public String
{
YCLASS(UIWidget,String)
YNOCOPY(UIWidget); // no automatic copies please
public:
/**
@ -765,6 +887,14 @@ public:
virtual bool getSelect(String& item)
{ return false; }
/**
* Retrieve widget's multiple selection
* @param items List to be to filled with selection's contents
* @return True if the operation was successfull
*/
virtual bool getSelect(NamedList& items)
{ return false; }
/**
* Append or insert text lines to this widget
* @param lines List containing the lines
@ -809,6 +939,7 @@ public:
*/
class YATE_API UIFactory : public String
{
YCLASS(UIFactory,String)
YNOCOPY(UIFactory); // no automatic copies please
public:
/**
@ -863,6 +994,7 @@ private:
*/
class YATE_API Client : public MessageReceiver
{
YCLASS(Client,MessageReceiver)
friend class Window;
friend class ClientChannel;
friend class ClientDriver;
@ -889,6 +1021,7 @@ public:
EngineStart,
TransferNotify,
UserData,
FileInfo,
// Starting value for custom relays
MsgIdCount
};
@ -1147,6 +1280,16 @@ public:
*/
virtual bool select(Window* wnd, const String& name, const String& item, const String& text = String::empty());
/**
* Handle 'select' with multiple items actions from user interface. Enqueue an ui.event message if
* the action is not handled by a client logic
* @param wnd The window in which the user selected the object
* @param name The action's name
* @param items List containing the selection
* @return True if the action was handled by a client logic
*/
virtual bool select(Window* wnd, const String& name, const NamedList& items);
/**
* Check if the client is using more then 1 thread
* @return True if the client is using more then 1 thread
@ -1209,7 +1352,8 @@ public:
bool addTableRow(const String& name, const String& item, const NamedList* data = 0,
bool atStart = false, Window* wnd = 0, Window* skip = 0);
/** Append or update several table rows at once
/**
* Append or update several table rows at once
* @param name Name of the element
* @param data Parameters to initialize the rows with
* @param prefix Prefix to match (and remove) in parameter names
@ -1269,6 +1413,16 @@ public:
bool updateTableRows(const String& name, const NamedList* data, bool atStart = false,
Window* wnd = 0, Window* skip = 0);
/**
* Show or hide control busy state
* @param name Name of the element
* @param on True to show, false to hide
* @param wnd Optional window owning the element
* @param skip Optional window to skip if wnd is 0
* @return True if all the operations were successfull
*/
bool setBusy(const String& name, bool on, Window* wnd = 0, Window* skip = 0);
/**
* Get an element's text
* @param name Name of the element
@ -1283,6 +1437,16 @@ public:
bool getCheck(const String& name, bool& checked, Window* wnd = 0, Window* skip = 0);
bool getSelect(const String& name, String& item, Window* wnd = 0, Window* skip = 0);
/**
* Retrieve an element's multiple selection
* @param name Name of the element
* @param items List to be to filled with selection's contents
* @param wnd Optional window owning the element
* @param skip Optional window to skip if wnd is 0
* @return True if the operation was successfull
*/
bool getSelect(const String& name, NamedList& items, Window* wnd = 0, Window* skip = 0);
/**
* Build a menu from a list of parameters and add it to a target.
* @param params Menu build parameters (list name is the menu name).
@ -1779,6 +1943,16 @@ public:
*/
static void plain2html(String& buf, bool spaceEol = false);
/**
* Find a list parameter by its value
* @param list The list
* @param value Parameter value
* @param skip Optional parameter to skip
* @return NamedString pointer, 0 if not found
*/
static NamedString* findParamByValue(NamedList& list, const String& value,
NamedString* skip = 0);
/**
* Decode flags from dictionary values found in a list of parameters
* Flags are allowed to begin with '!' to reset
@ -1850,6 +2024,13 @@ public:
static bool removeLastNameInPath(String& dest, const String& path, char sep = 0,
const String& equalOnly = String::empty());
/**
* Add a formatted log line
* @param format Text format
* @return True on success
*/
static bool addToLogFormatted(const char* format, ...);
static Configuration s_settings; // Client settings
static Configuration s_actions; // Logic preferrences
static Configuration s_accounts; // Accounts
@ -1924,6 +2105,7 @@ protected:
*/
class YATE_API ClientChannel : public Channel
{
YCLASS(ClientChannel,Channel)
friend class ClientDriver;
YNOCOPY(ClientChannel); // no automatic copies please
public:
@ -2321,6 +2503,7 @@ protected:
*/
class YATE_API ClientDriver : public Driver
{
YCLASS(ClientDriver,Driver)
friend class ClientChannel; // Reset active channel's id
YNOCOPY(ClientDriver); // No automatic copies please
public:
@ -2451,6 +2634,7 @@ protected:
*/
class YATE_API ClientLogic : public GenObject
{
YCLASS(ClientLogic,GenObject)
friend class Client;
YNOCOPY(ClientLogic); // no automatic copies please
public:
@ -2518,6 +2702,16 @@ public:
const String& text = String::empty())
{ return false; }
/**
* Handle 'select' with multiple items actions from user interface
* @param wnd The window in which the user did something
* @param name The object's name
* @param items List of selected items
* @return True if the action was handled
*/
virtual bool select(Window* wnd, const String& name, const NamedList& items)
{ return false; }
/**
* Set a client's parameter. Save the settings file and/or update interface
* @param param Parameter's name
@ -3032,6 +3226,7 @@ private:
int m_prio; // Logics priority
};
class FtManager;
/**
* This class implements the default client behaviour.
@ -3039,6 +3234,7 @@ private:
*/
class YATE_API DefaultLogic : public ClientLogic
{
YCLASS(DefaultLogic,ClientLogic)
YNOCOPY(DefaultLogic); // no automatic copies please
public:
/**
@ -3082,6 +3278,15 @@ public:
virtual bool select(Window* wnd, const String& name, const String& item,
const String& text = String::empty());
/**
* Handle 'select' with multiple items actions from user interface
* @param wnd The window in which the user did something
* @param name The object's name
* @param items List of selected items
* @return True if the action was handled
*/
virtual bool select(Window* wnd, const String& name, const NamedList& items);
/**
* Set a client's parameter. Save the settings file and/or update interface
* @param param Parameter's name
@ -3543,6 +3748,14 @@ protected:
*/
virtual bool handleUserData(Message& msg, bool& stopLogic);
/**
* Handle file.info messages.
* @param msg The message
* @param stopLogic Stop notifying other logics if set to true on return
* @return True if handled
*/
virtual bool handleFileInfo(Message& msg, bool& stopLogic);
/**
* Show a generic notification
* @param text Notification text
@ -3628,8 +3841,29 @@ private:
bool handleChanShowExtra(Window* wnd, bool show, const String& chan, bool conf);
// Handle conf/transfer start actions in channel item
bool handleChanItemConfTransfer(bool conf, const String& name, Window* wnd);
// Handle file share(d) related action
bool handleFileShareAction(Window* wnd, const String& name, NamedList* params);
// Handle file share(d) related select
bool handleFileShareSelect(Window* wnd, const String& name, const String& item,
const String& text, const NamedList* items);
// Handle file share(d) item changes from UI
bool handleFileShareItemChanged(Window* wnd, const String& name, const String& item,
const NamedList& params);
// Handle file share(d) drop events
bool handleFileShareDrop(bool askOnly, Window* wnd, const String& name,
NamedList& params, bool& retVal);
// Handle list item change action
bool handleListItemChanged(Window* wnd, const String& list, const String& item,
const NamedList& params);
// Handle drop events
bool handleDrop(bool askOnly, Window* wnd, const String& name,
NamedList& params);
// Handle file share info changed notification
void handleFileSharedChanged(ClientAccount* a, const String& contact,
const String& inst);
ClientAccountList* m_accounts; // Accounts list (always valid)
FtManager* m_ftManager; // Private file manager
};
@ -3641,6 +3875,7 @@ class YATE_API ClientAccount : public RefObject, public Mutex
{
friend class ClientContact;
friend class MucRoom;
YCLASS(ClientAccount,RefObject)
YNOCOPY(ClientAccount); // no automatic copies please
public:
/**
@ -3947,6 +4182,7 @@ private:
*/
class YATE_API ClientAccountList : public String, public Mutex
{
YCLASS(ClientAccountList,String)
YNOCOPY(ClientAccountList); // no automatic copies please
public:
/**
@ -4100,8 +4336,17 @@ private:
class YATE_API ClientContact : public RefObject
{
friend class ClientAccount;
YCLASS(ClientContact,RefObject)
YNOCOPY(ClientContact); // no automatic copies please
public:
/**
* Subscription flags
*/
enum Subscription {
SubFrom = 0x01,
SubTo = 0x02,
};
/**
* Constructor. Append itself to the owner's list
* @param owner The contact's owner
@ -4151,6 +4396,34 @@ public:
inline void setUri(const char* u)
{ m_uri = u; }
/**
* Retrieve contact subscription
* @return Contact subscription string
*/
inline const String& subscriptionStr() const
{ return m_subscription; }
/**
* Check if contact is subscribed to our presence
* @return True if contact is subscribed to our presence
*/
inline bool subscriptionFrom() const
{ return 0 != m_sub.flag(SubFrom); }
/**
* Check we are subscribed to contact's presence
* @return True if we are subscribed to contact's presence
*/
inline bool subscriptionTo() const
{ return 0 != m_sub.flag(SubTo); }
/**
* Set contact's subscription
* @param value Subscription value
* @return True if changed
*/
bool setSubscription(const String& value);
/**
* Get the resource list of this contact
* @return The resource list of this contact
@ -4249,10 +4522,8 @@ public:
* @param inst Instance name
* @return Destination string
*/
inline String& buildInstanceId(String& dest, const String& inst = String::empty()) {
dest << m_id << "|" << inst.uriEscape('|');
return dest;
}
inline String& buildInstanceId(String& dest, const String& inst = String::empty())
{ return buildContactInstanceId(dest,m_id,inst); }
/**
* Build a string from prefix and contact id hash
@ -4481,6 +4752,82 @@ public:
*/
virtual bool removeResource(const String& id);
/**
* Retrieve files and folders we share with this contact
* @return List of files and folders we share with this contact
*/
inline NamedList& share()
{ return m_share; }
/**
* Check if the list of share contains something
* @return True if share list is not empty
*/
inline bool haveShare() const
{ return 0 != m_share.getParam(0); }
/**
* (re)load share list
*/
virtual void updateShare();
/**
* Save share list
*/
virtual void saveShare();
/**
* Clear share list
*/
virtual void clearShare();
/**
* Set a directory we share with this contact
* If share name is not empty it must be unique. Fails if another share has the same name
* @param name Share name
* @param path Directory path
* @param save True to save now if changed
* @return True if changed
*/
virtual bool setShareDir(const String& name, const String& path, bool save = true);
/**
* Remove a share item
* @param name Share name
* @param save True to save now if changed
* @return True if changed
*/
virtual bool removeShare(const String& name, bool save = true);
/**
* Retrieve shared data
* @return Shared data list
*/
inline ObjList& shared()
{ return m_shared; }
/**
* Check if the list of shared contains something
* @return True if shared list is not empty
*/
bool haveShared() const;
/**
* Retrieve shared data for a given resource
* @param name Resource name
* @param create True to create if not found
* @return True if changed
*/
virtual ClientDir* getShared(const String& name, bool create = false);
/**
* Remove shared data
* @param name Resource name to remove, empty to remove all
* @param removed Optional pointer to removed directory
* @return True if changed
*/
virtual bool removeShared(const String& name = String::empty(), ClientDir** removed = 0);
/**
* Build a contact id to be used in UI (all strings are URI escaped using extra '|' character)
* @param dest Destination string
@ -4517,6 +4864,19 @@ public:
static void splitContactInstanceId(const String& src, String& account,
String& contact, String* instance = 0);
/**
* Build a contact instance id to be used in UI
* @param dest Destination string
* @param cId Contact id
* @param inst Instance name
* @return Destination string
*/
static inline String& buildContactInstanceId(String& dest, const String& cId,
const String& inst = String::empty()) {
dest << cId << "|" << inst.uriEscape('|');
return dest;
}
// Chat window prefix
static String s_chatPrefix;
// Docked chat window name
@ -4529,7 +4889,6 @@ public:
static String s_chatInput;
String m_name; // Contact's display name
String m_subscription; // Presence subscription state
NamedList m_params; // Optional contact extra params
protected:
@ -4554,11 +4913,15 @@ protected:
ClientAccount* m_owner; // The account owning this contact
bool m_online; // Online flag
String m_id; // The contact's id
String m_subscription; // Presence subscription state
Flags32 m_sub; // Subscription flags
URI m_uri; // The contact's URI
ObjList m_resources; // The contact's resource list
ObjList m_groups; // The group(s) this contact belongs to
bool m_dockedChat; // Docked chat flag
String m_chatWndName; // Chat window name if any
NamedList m_share; // List of files and folders we share
ObjList m_shared; // List of shared. Each entry is a ClientDir whose name is the resource
};
/**
@ -4584,6 +4947,16 @@ public:
Xa = 7,
};
/**
* Resource capabilities
*/
enum Capability {
CapAudio = 0x00000001, // Audio
CapFileTransfer = 0x00000002, // File transfer support
CapFileInfo = 0x00000004, // File info share support
CapRsm = 0x00000008, // Result set management support
};
/**
* Constructor
* @param id The resource's id
@ -4591,13 +4964,13 @@ public:
* @param audio True (default) if the resource has audio capability
*/
inline explicit ClientResource(const char* id, const char* name = 0, bool audio = true)
: m_id(id), m_name(name ? name : id), m_audio(audio), m_fileTransfer(false),
: m_id(id), m_name(name ? name : id), m_caps(audio ? CapAudio : 0),
m_priority(0), m_status(Offline)
{ }
/**
* Get a string representation of this object
* @return The account's id
* @return The resource id
*/
virtual const String& toString() const
{ return m_id; }
@ -4630,29 +5003,28 @@ public:
inline const char* text() const
{ return m_text ? m_text.c_str() : statusDisplayText(m_status); }
/**
* Retrieve resource capabilities
* @return Resource capabilities flags
*/
inline Flags32& caps()
{ return m_caps; }
/**
* Update resource audio capability
* @param ok The new audio capability value
* @return True if changed
*/
inline bool setAudio(bool ok) {
if (m_audio == ok)
return false;
m_audio = ok;
return true;
}
inline bool setAudio(bool ok)
{ return m_caps.changeFlagCheck(CapAudio,ok); }
/**
* Update resource file transfer capability
* @param ok The new file transfer value
* @return True if changed
*/
inline bool setFileTransfer(bool ok) {
if (m_fileTransfer == ok)
return false;
m_fileTransfer = ok;
return true;
}
inline bool setFileTransfer(bool ok)
{ return m_caps.changeFlagCheck(CapFileTransfer,ok); }
/**
* Update resource priority
@ -4704,10 +5076,14 @@ public:
*/
static const TokenDict s_statusName[];
/**
* resource.notify capability names
*/
static const TokenDict s_resNotifyCaps[];
String m_id; // The resource id
String m_name; // Resource display name
bool m_audio; // Audio capability flag
bool m_fileTransfer; // File transfer capability flag
Flags32 m_caps; // Resource capabilities
int m_priority; // Resource priority
int m_status; // Resource status
String m_text; // Resource status text
@ -5089,6 +5465,7 @@ private:
*/
class YATE_API DurationUpdate : public RefObject
{
YCLASS(DurationUpdate,RefObject)
YNOCOPY(DurationUpdate); // no automatic copies please
public:
/**
@ -5195,6 +5572,7 @@ protected:
*/
class YATE_API ClientSound : public String
{
YCLASS(ClientSound,String)
YNOCOPY(ClientSound); // no automatic copies please
public:
/**
@ -5380,6 +5758,224 @@ protected:
String m_channel; // Utility channel using this sound
};
/**
* Base class for file/dir items
* @short A file/directory item
*/
class YATE_API ClientFileItem : public GenObject
{
YCLASS(ClientFileItem,GenObject)
YNOCOPY(ClientFileItem); // no automatic copies please
public:
/**
* Constructor
* @param name Item name
*/
inline ClientFileItem(const char* name)
: m_name(name)
{}
/**
* Retrieve the item name
* @return Item name
*/
inline const String& name() const
{ return m_name; }
/**
* Check if this item is a directory
* @return ClientDir pointer or 0
*/
virtual ClientDir* directory()
{ return 0; }
/**
* Check if this item is a file
* @return ClientDir pointer or 0
*/
virtual ClientFile* file()
{ return 0; }
/**
* Retrieve the item name
* @return Item name
*/
virtual const String& toString() const
{ return name(); }
private:
ClientFileItem() {} // No default constructor
String m_name;
};
/**
* This class holds directory info
* @short A directory
*/
class YATE_API ClientDir: public ClientFileItem
{
YCLASS(ClientDir,ClientFileItem)
public:
/**
* Constructor
* @param name Directory name
*/
inline ClientDir(const char* name)
: ClientFileItem(name), m_updated(false)
{}
/**
* Copy constructor. Copy known children types
* @param other Source object
*/
inline ClientDir(const ClientDir& other)
: ClientFileItem(other.name()), m_updated(other.updated())
{ copyChildren(other.m_children); }
/**
* Retrieve the children list
* @return Children list
*/
inline ObjList& children()
{ return m_children; }
/**
* Check if children were updated
* @return True if children list was updated
*/
inline bool updated() const
{ return m_updated; }
/**
* Set children updated flag
* @return New value for children updated flag
*/
inline void updated(bool on)
{ m_updated = on; }
/**
* Recursively check if all (sub)directores were updated
* @return True if all (sub)directores were updated
*/
bool treeUpdated() const;
/**
* Build and add a sub-directory if not have one already
* Replace an existing file with the same name
* @param path Directory name
* @return ClientDir pointer or 0 on failure
*/
ClientDir* addDir(const String& name);
/**
* Build sub directories from path
* @param path Directory path
* @param sep Path separator
* @return ClientDir pointer or 0 on failure
*/
ClientDir* addDirPath(const String& path, const char* sep = "/");
/**
* Add a copy of known children types
* @param list List of ClientFileItem objects to copy
*/
void copyChildren(const ObjList& list);
/**
* Add a list of children, consume the objects
* @param list List of ClientFileItem objects to add
*/
void addChildren(ObjList& list);
/**
* Add an item. Remove another item with the same name if exists
* @param item Item to add
* @return True on success
*/
bool addChild(ClientFileItem* item);
/**
* Find a child by path
* @param path Item path
* @param sep Path separator
* @return ClientFileItem pointer or 0
*/
ClientFileItem* findChild(const String& path, const char* sep = "/");
/**
* Find a child by name
* @param name Item name
* @return ClientFileItem pointer or 0
*/
inline ClientFileItem* findChildName(const String& name) {
ObjList* o = m_children.find(name);
return o ? static_cast<ClientFileItem*>(o->get()) : 0;
}
/**
* Check if this item is a directory
* @return ClientDir pointer
*/
virtual ClientDir* directory()
{ return this; }
protected:
ObjList m_children;
bool m_updated;
};
/**
* This class holds file info
* @short A file
*/
class YATE_API ClientFile: public ClientFileItem
{
YCLASS(ClientFile,ClientFileItem)
public:
/**
* Constructor
* @param name File name
* @param params Optional file parameters
*/
inline ClientFile(const char* name, const NamedList* params = 0)
: ClientFileItem(name), m_params("") {
if (params)
m_params.copyParams(*params);
}
/**
* Copy constructor
* @param other Source object
*/
inline ClientFile(const ClientFile& other)
: ClientFileItem(other.name()), m_params(other.params())
{}
/**
* Retrieve item parameters
* @return Item parameters
*/
inline NamedList& params()
{ return m_params; }
/**
* Retrieve item parameters
* @return Item parameters
*/
inline const NamedList& params() const
{ return m_params; }
/**
* Check if this item is a file
* @return ClientFile pointer
*/
virtual ClientFile* file()
{ return this; }
protected:
NamedList m_params;
};
}; // namespace TelEngine
#endif /* __YATECBASE_H */