Added support for proper handling of call history.
git-svn-id: http://yate.null.ro/svn/yate/trunk@776 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
9b40ddc480
commit
8e639a1747
|
@ -389,6 +389,13 @@ static gboolean widgetCbShow(GtkWidget* wid, gpointer dat)
|
|||
return GTKClient::setVisible(name);
|
||||
}
|
||||
|
||||
static gboolean widgetCbChanged(GtkRange* range, gpointer dat)
|
||||
{
|
||||
const gchar* name = gtk_widget_get_name((GtkWidget*)range);
|
||||
Debug(GTKDriver::self(),DebugAll,"widgetCbChanged(%p,%p) '%s'",range,dat,name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean widgetCbSwitch(GtkNotebook* nbk, GtkNotebookPage* page, guint page_num, gpointer dat)
|
||||
{
|
||||
const gchar* name = gtk_widget_get_name(GTK_WIDGET(nbk));
|
||||
|
@ -616,6 +623,16 @@ static GtkWidget* gtkTableNew(const gchar* text)
|
|||
return table;
|
||||
}
|
||||
|
||||
static GtkWidget* gtkHscaleNew(const gchar* text)
|
||||
{
|
||||
return gtk_hscale_new_with_range(0,100,10);
|
||||
}
|
||||
|
||||
static GtkWidget* gtkVscaleNew(const gchar* text)
|
||||
{
|
||||
return gtk_vscale_new_with_range(0,100,10);
|
||||
}
|
||||
|
||||
static WidgetMaker s_widgetMakers[] = {
|
||||
{ "label", gtkLeftLabelNew, 0, 0 },
|
||||
{ "editor", gtkEntryNewWithText, "activate", G_CALLBACK(widgetCbAction) },
|
||||
|
@ -635,6 +652,8 @@ static WidgetMaker s_widgetMakers[] = {
|
|||
{ "button_icon", gtkButtonNew, "clicked", G_CALLBACK(widgetCbMinimize) },
|
||||
{ "button_hide", gtkButtonNew, "clicked", G_CALLBACK(widgetCbHide) },
|
||||
{ "button_max", gtkButtonNew, "clicked", G_CALLBACK(widgetCbMaximize) },
|
||||
{ "hscale", gtkHscaleNew, "value-changed", G_CALLBACK(widgetCbChanged) },
|
||||
{ "vscale", gtkVscaleNew, "value-changed", G_CALLBACK(widgetCbChanged) },
|
||||
{ 0, 0, 0, 0 },
|
||||
};
|
||||
// { "", gtk__new, "", },
|
||||
|
@ -1315,6 +1334,10 @@ bool GTKWindow::setText(GtkWidget* wid, const String& text)
|
|||
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(wid)->entry),text.safe());
|
||||
return true;
|
||||
}
|
||||
if (GTK_IS_ADJUSTMENT(wid)) {
|
||||
gtk_adjustment_set_value(GTK_ADJUSTMENT(wid),text.toDouble());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -371,6 +371,7 @@ int Client::s_changing = 0;
|
|||
static Configuration s_accounts;
|
||||
static Configuration s_contacts;
|
||||
static Configuration s_providers;
|
||||
static Configuration s_history;
|
||||
|
||||
// Parameters that are stored with account
|
||||
static const char* s_accParams[] = {
|
||||
|
@ -523,6 +524,15 @@ void Client::initClient()
|
|||
}
|
||||
}
|
||||
|
||||
s_history = Engine::configFile("client_history");
|
||||
s_history.load();
|
||||
n = s_history.sections();
|
||||
for (i=0; i<n; i++) {
|
||||
NamedList* sect = s_history.getSection(i);
|
||||
if (sect)
|
||||
updateCallHist(*sect);
|
||||
}
|
||||
|
||||
bool tmp =
|
||||
getWindow("channels") || hasElement("channels") ||
|
||||
getWindow("lines") || hasElement("lines");
|
||||
|
@ -1148,8 +1158,21 @@ bool Client::action(Window* wnd, const String& name)
|
|||
}
|
||||
// outgoing (placed) call log actions
|
||||
else if (name == "log_out_clear") {
|
||||
if (clearTable("log_outgoing"))
|
||||
if (clearTable("log_outgoing")) {
|
||||
for (unsigned int i = 0; i < s_history.sections(); i++) {
|
||||
NamedList* sect = s_history.getSection(i);
|
||||
if (!sect)
|
||||
continue;
|
||||
String* dir = sect->getParam("direction");
|
||||
// directions are backwards
|
||||
if (dir && (*dir == "incoming")) {
|
||||
s_history.clearSection(*sect);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
s_history.save();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if ((name == "log_out_call") || (name == "log_outgoing")) {
|
||||
NamedList log("");
|
||||
|
@ -1163,8 +1186,21 @@ bool Client::action(Window* wnd, const String& name)
|
|||
}
|
||||
// incoming (received) call log actions
|
||||
else if (name == "log_in_clear") {
|
||||
if (clearTable("log_incoming"))
|
||||
if (clearTable("log_incoming")) {
|
||||
for (unsigned int i = 0; i < s_history.sections(); i++) {
|
||||
NamedList* sect = s_history.getSection(i);
|
||||
if (!sect)
|
||||
continue;
|
||||
String* dir = sect->getParam("direction");
|
||||
// directions are backwards, remember?
|
||||
if (dir && (*dir == "outgoing")) {
|
||||
s_history.clearSection(*sect);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
s_history.save();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if ((name == "log_in_call") || (name == "log_incoming")) {
|
||||
NamedList log("");
|
||||
|
@ -1178,8 +1214,11 @@ bool Client::action(Window* wnd, const String& name)
|
|||
}
|
||||
// mixed call log actions
|
||||
else if (name == "log_clear") {
|
||||
if (clearTable("log_global"))
|
||||
if (clearTable("log_global")) {
|
||||
s_history.clearSection();
|
||||
s_history.save();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// unknown/unhandled - generate a message for them
|
||||
|
@ -1380,7 +1419,7 @@ bool Client::callIncoming(const String& caller, const String& dest, Message* msg
|
|||
if (msg && msg->userData()) {
|
||||
CallEndpoint* ch = static_cast<CallEndpoint*>(msg->userData());
|
||||
lockOther();
|
||||
ClientChannel* cc = new ClientChannel(caller,ch->id());
|
||||
ClientChannel* cc = new ClientChannel(caller,ch->id(),msg);
|
||||
unlockOther();
|
||||
if (cc->connect(ch,msg->getValue("reason"))) {
|
||||
m_activeId = cc->id();
|
||||
|
@ -1423,14 +1462,40 @@ bool Client::callRouting(const String& caller, const String& called, Message* ms
|
|||
|
||||
void Client::updateCDR(const Message& msg)
|
||||
{
|
||||
String* dir = msg.getParam("direction");
|
||||
if (!dir)
|
||||
if (!updateCallHist(msg))
|
||||
return;
|
||||
String* id = msg.getParam("billid");
|
||||
if (!id || id->null())
|
||||
String id = msg.getParam("billid");
|
||||
if (id.null())
|
||||
id = msg.getParam("id");
|
||||
if (!id || id->null())
|
||||
// it worked before - but paranoia can be fun
|
||||
if (id.null())
|
||||
return;
|
||||
while (s_history.sections() >= 20) {
|
||||
NamedList* sect = s_history.getSection(0);
|
||||
if (!sect)
|
||||
break;
|
||||
s_history.clearSection(*sect);
|
||||
}
|
||||
unsigned int n = msg.length();
|
||||
for (unsigned int i = 0; i < n; i++) {
|
||||
NamedString* param = msg.getParam(i);
|
||||
if (!param)
|
||||
continue;
|
||||
s_history.setValue(id,param->name(),param->c_str());
|
||||
}
|
||||
s_history.save();
|
||||
}
|
||||
|
||||
bool Client::updateCallHist(const NamedList& params)
|
||||
{
|
||||
String* dir = params.getParam("direction");
|
||||
if (!dir)
|
||||
return false;
|
||||
String* id = params.getParam("billid");
|
||||
if (!id || id->null())
|
||||
id = params.getParam("id");
|
||||
if (!id || id->null())
|
||||
return false;
|
||||
String table;
|
||||
// remember, directions are opposite of what the user expects
|
||||
if (*dir == "outgoing")
|
||||
|
@ -1438,9 +1503,10 @@ void Client::updateCDR(const Message& msg)
|
|||
else if (*dir == "incoming")
|
||||
table = "log_outgoing";
|
||||
else
|
||||
return;
|
||||
addTableRow(table,*id,&msg);
|
||||
addTableRow("log_global",*id,&msg);
|
||||
return false;
|
||||
bool ok = addTableRow(table,*id,¶ms);
|
||||
ok = addTableRow("log_global",*id,¶ms) || ok;
|
||||
return ok;
|
||||
}
|
||||
|
||||
void Client::clearActive(const String& id)
|
||||
|
@ -1562,13 +1628,18 @@ bool UICdrHandler::received(Message &msg)
|
|||
if (!Client::self())
|
||||
return false;
|
||||
|
||||
String* op = msg.getParam("operation");
|
||||
if (!(op && (*op == "finalize")))
|
||||
return false;
|
||||
op = msg.getParam("chan");
|
||||
if (!(op && op->startsWith("client/",false)))
|
||||
return false;
|
||||
|
||||
// block until client finishes initialization
|
||||
while (!Client::self()->initialized())
|
||||
Thread::msleep(10);
|
||||
|
||||
String* op = msg.getParam("operation");
|
||||
if (op && (*op == "finalize"))
|
||||
Client::self()->updateCDR(msg);
|
||||
Client::self()->updateCDR(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1681,7 +1752,7 @@ bool UIUserHandler::received(Message &msg)
|
|||
|
||||
// IMPORTANT: having a target means "from inside Yate to the user"
|
||||
// An user initiated call must be incoming (no target)
|
||||
ClientChannel::ClientChannel(const String& party, const char* target)
|
||||
ClientChannel::ClientChannel(const String& party, const char* target, const Message* msg)
|
||||
: Channel(ClientDriver::self(),0,(target != 0)),
|
||||
m_party(party), m_line(0), m_flashing(false),
|
||||
m_canAnswer(false), m_canTransfer(false), m_canConference(false)
|
||||
|
@ -1695,7 +1766,13 @@ ClientChannel::ClientChannel(const String& party, const char* target)
|
|||
update(false);
|
||||
if (Client::self())
|
||||
Client::self()->addChannel(this);
|
||||
Engine::enqueue(message("chan.startup"));
|
||||
Message* s = message("chan.startup");
|
||||
if (msg) {
|
||||
s->setParam("caller",msg->getValue("caller"));
|
||||
s->setParam("called",msg->getValue("called"));
|
||||
s->setParam("billid",msg->getValue("billid"));
|
||||
}
|
||||
Engine::enqueue(s);
|
||||
}
|
||||
|
||||
ClientChannel::~ClientChannel()
|
||||
|
|
|
@ -341,6 +341,7 @@ protected:
|
|||
virtual void initWindows();
|
||||
virtual void initClient();
|
||||
virtual void setChannelDisplay(ClientChannel* chan);
|
||||
virtual bool updateCallHist(const NamedList& params);
|
||||
void addChannel(ClientChannel* chan);
|
||||
void delChannel(ClientChannel* chan);
|
||||
void setChannel(ClientChannel* chan);
|
||||
|
@ -372,7 +373,7 @@ class YATE_API ClientChannel : public Channel
|
|||
{
|
||||
friend class ClientDriver;
|
||||
public:
|
||||
ClientChannel(const String& party, const char* target = 0);
|
||||
ClientChannel(const String& party, const char* target = 0, const Message* msg = 0);
|
||||
virtual ~ClientChannel();
|
||||
virtual bool msgProgress(Message& msg);
|
||||
virtual bool msgRinging(Message& msg);
|
||||
|
|
Loading…
Reference in New Issue