Show a notification when a contact add, change or remove succeeded or failed. Show a notification when contact list retrieval fails.

git-svn-id: http://voip.null.ro/svn/yate@4322 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2011-04-19 09:38:17 +00:00
parent 9243223463
commit 07b18bc9f5
4 changed files with 144 additions and 47 deletions

View File

@ -318,6 +318,7 @@ static const String s_inviteContacts = "invite_contacts"; // List of contacts
// Actions
static const String s_actionShowCallsList = "showCallsList";
static const String s_actionShowNotification = "showNotification";
static const String s_actionShowInfo = "showNotificationInfo";
static const String s_actionPendingChat = "showPendingChat";
static const String s_actionCall = "call";
static const String s_actionAnswer = "answer";
@ -521,6 +522,22 @@ static inline bool setChangedParam(NamedList& dest, const String& param,
return true;
}
// Append failure reason/error to a string
static void addError(String& buf, NamedList& list)
{
String* error = list.getParam("error");
String* reason = list.getParam("reason");
if (TelEngine::null(error)) {
if (TelEngine::null(reason))
return;
error = reason;
reason = 0;
}
buf.append(*error,": ");
if (!TelEngine::null(reason))
buf << " (" << *reason << ")";
}
// Build contact name: name <uri>
static inline void buildContactName(String& buf, ClientContact& c)
{
@ -2525,6 +2542,8 @@ static bool dropFileTransferItem(const String& id)
// Add a tray icon to the mainwindow stack
static bool addTrayIcon(const String& type)
{
if (!type)
return false;
int prio = 0;
String triggerAction;
NamedList* iconParams = 0;
@ -2546,12 +2565,19 @@ static bool addTrayIcon(const String& type)
triggerAction = s_actionShowCallsList;
specific = "View calls";
}
else if (type == "notification") {
prio = Client::TrayIconNotification;
else if (type == "notification" || type == "info") {
iconParams = new NamedList(name);
iconParams->addParam("icon",Client::s_skinPath + "tray_notification.png");
if (type == "notification") {
prio = Client::TrayIconNotification;
iconParams->addParam("icon",Client::s_skinPath + "tray_notification.png");
triggerAction = s_actionShowNotification;
}
else {
prio = Client::TrayIconInfo;
iconParams->addParam("icon",Client::s_skinPath + "tray_info.png");
triggerAction = s_actionShowInfo;
}
info << "\r\nA notification is requiring your attention";
triggerAction = s_actionShowNotification;
specific = "View notifications";
}
else if (type == "incomingchat") {
@ -2583,7 +2609,8 @@ static bool addTrayIcon(const String& type)
// Remove a tray icon from mainwindow stack
static inline bool removeTrayIcon(const String& type)
{
return Client::removeTrayIcon("mainwindow","mainwindow_" + type + "_icon");
return type &&
Client::removeTrayIcon("mainwindow","mainwindow_" + type + "_icon");
}
// Notify incoming chat to the user
@ -4469,16 +4496,17 @@ bool DefaultLogic::action(Window* wnd, const String& name, NamedList* params)
if (name == "button_hide" && wnd)
return Client::self() && Client::self()->setVisible(wnd->toString(),false);
// Show/hide messages
bool showMsgs = (name == "messages_show" || name == s_actionShowNotification);
bool showMsgs = (name == "messages_show" || name == s_actionShowNotification ||
name == s_actionShowInfo);
if (showMsgs || name == "messages_close") {
if (name == s_actionShowNotification) {
removeTrayIcon("notification");
bool notif = (name == s_actionShowNotification);
if (notif || name == s_actionShowInfo) {
removeTrayIcon(notif ? "notification" : "info");
if (wnd && Client::valid())
Client::self()->setVisible(wnd->id(),true,true);
}
return showNotificationArea(showMsgs,wnd);
}
// Dialog actions
// Return 'true' to close the dialog
bool dlgRet = false;
@ -4920,8 +4948,10 @@ bool DefaultLogic::select(Window* wnd, const String& name, const String& item,
// No more notifications: remove the tray icon
if (name == "messages") {
if (!item)
if (!item) {
removeTrayIcon("notification");
removeTrayIcon("info");
}
return true;
}
@ -5925,47 +5955,27 @@ bool DefaultLogic::handleUserRoster(Message& msg, bool& stopLogic)
const String& oper = msg["operation"];
if (!oper)
return false;
bool fail = false;
bool remove = (oper != "update");
if (remove && oper != "delete") {
if (oper != "queryerror")
return false;
fail = true;
}
// Postpone message processing
if (Client::self()->postpone(msg,Client::UserRoster)) {
stopLogic = true;
return false;
}
int n = msg.getIntValue("contact.count");
if (n < 1 && !fail)
return false;
const String& account = msg["account"];
ClientAccount* a = account ? m_accounts->findAccount(account) : 0;
if (!a)
return false;
if (fail) {
String reason = msg["error"];
if (reason) {
const String& res = msg["reason"];
if (res)
reason << " (" << res << ")";
}
else
reason = msg["reason"];
NamedList list("");
NamedList* upd = buildNotifArea(list,"rosterreqfail",account,
String::empty(),"Friends list failure");
setGenericNotif(*upd,"Retry");
String text;
text << "Failed to retrieve the friends list";
text.append(reason,": ");
text.append(account,"\r\nAccount: ");
upd->addParam("text",text);
showNotificationArea(true,Client::self()->getWindow(s_wndMain),&list);
if (oper == "error" || oper == "queryerror" || oper == "result") {
showUserRosterNotification(a,oper,msg,msg["contact"]);
return false;
}
if (msg.getBoolValue("queryrsp"))
bool remove = (oper != "update");
if (remove && oper != "delete")
return false;
int n = msg.getIntValue("contact.count");
if (n < 1)
return false;
bool queryRsp = msg.getBoolValue("queryrsp");
if (queryRsp)
removeNotifArea("rosterreqfail",account);
ObjList removed;
NamedList chatlist("");
@ -5983,6 +5993,8 @@ bool DefaultLogic::handleUserRoster(Message& msg, bool& stopLogic)
if (remove) {
if (!c)
continue;
if (!queryRsp)
showUserRosterNotification(a,oper,msg,uri);
removed.append(a->removeContact(id,false));
continue;
}
@ -6002,9 +6014,13 @@ bool DefaultLogic::handleUserRoster(Message& msg, bool& stopLogic)
changed = setChangedString(c->m_subscription,sub) || changed;
// Get groups
changed = c->setGroups(msg,pref + "group") || changed;
// Update info window if displayed
if (changed)
if (changed) {
// Update info window if displayed
updateContactInfo(c);
// Show update notification
if (!queryRsp)
showUserRosterNotification(a,oper,msg,uri,newContact);
}
if (!(changed && a->hasChat()))
continue;
NamedList* p = new NamedList(c->toString());
@ -8646,16 +8662,17 @@ bool DefaultLogic::handleMucResNotify(Message& msg, ClientAccount* acc, const St
}
// Show/hide the notification area (messages)
bool DefaultLogic::showNotificationArea(bool show, Window* wnd, NamedList* upd)
bool DefaultLogic::showNotificationArea(bool show, Window* wnd, NamedList* upd,
const char* notif)
{
if (!Client::self())
return false;
if (upd) {
Client::self()->updateTableRows("messages",upd,false,wnd);
addTrayIcon("notification");
addTrayIcon(notif);
}
else if (!show)
removeTrayIcon("notification");
removeTrayIcon(notif);
NamedList p("");
const char* ok = String::boolText(show);
p.addParam("check:messages_show",ok);
@ -8666,6 +8683,78 @@ bool DefaultLogic::showNotificationArea(bool show, Window* wnd, NamedList* upd)
return true;
}
// Show a roster change or failure notification
void DefaultLogic::showUserRosterNotification(ClientAccount* a, const String& oper,
Message& msg, const String& contactUri, bool newContact)
{
if (!a)
return;
NamedList list("");
NamedList* upd = 0;
String text;
const char* firstButton = 0;
bool update = (oper == "update");
const char* notif = "notification";
ClientContact* c = contactUri ? a->findContactByUri(contactUri) : 0;
String cName;
if (c)
buildContactName(cName,*c);
else
cName = contactUri;
if (update || oper == "delete") {
if (!c)
return;
notif = "info";
upd = buildNotifArea(list,"generic",a->toString(),contactUri,
"Friends list changed");
text << (update ? (newContact ? "Added" : "Updated") : "Removed");
text << " friend " << cName;
}
else if (oper == "error") {
if (!contactUri)
return;
ClientContact* c = a->findContactByUri(contactUri);
const String& req = msg["requested_operation"];
const char* what = 0;
if (req == "update") {
upd = buildNotifArea(list,"contactupdatefail",a->toString(),
contactUri,"Friend update failure");
what = (c ? "update" : "add");
}
else if (req == "delete") {
if (!c)
return;
upd = buildNotifArea(list,"contactremovefail",a->toString(),
contactUri,"Friend delete failure");
what = "remove";
}
else
return;
text << "Failed to " << what << " friend " << cName;
addError(text,msg);
}
else if (oper == "queryerror") {
upd = buildNotifArea(list,"rosterreqfail",a->toString(),String::empty(),
"Friends list failure");
firstButton = "Retry";
text << "Failed to retrieve the friends list";
addError(text,msg);
}
else {
if (oper == "result")
Debug(ClientDriver::self(),DebugAll,"Contact %s for '%s' account=%s confirmed",
msg.getValue("requested_operation"),msg.getValue("contact"),
a->toString().c_str());
return;
}
setGenericNotif(*upd,firstButton);
Debug(ClientDriver::self(),DebugAll,"Account '%s'. %s",
a->toString().c_str(),text.c_str());
text << "\r\nAccount: " << a->toString();
upd->addParam("text",text);
showNotificationArea(true,Client::self()->getWindow(s_wndMain),&list,notif);
}
// Handle actions from notification area. Return true if handled
bool DefaultLogic::handleNotificationAreaAction(const String& action, Window* wnd)
{

View File

@ -1988,6 +1988,8 @@ QTextEdit {
<string>property:_yate_itemui=incomingfile:messages_okrejignore.ui</string>
<string>property:_yate_itemui=rosterreqfail:messages_generic.ui</string>
<string>property:_yate_itemui=noaudio:messages_generic.ui</string>
<string>property:_yate_itemui=contactupdatefail:messages_generic.ui</string>
<string>property:_yate_itemui=contactremovefail:messages_generic.ui</string>
</stringlist>
</property>
</widget>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -822,6 +822,7 @@ public:
*/
enum TrayIconType {
TrayIconMain = 0,
TrayIconInfo = 1000,
TrayIconIncomingChat = 3000,
TrayIconNotification = 5000,
TrayIconIncomingCall = 10000,
@ -3226,8 +3227,13 @@ private:
bool handleMucResNotify(Message& msg, ClientAccount* acc, const String& contact,
const String& instance, const String& operation);
// Show/hide the notification area (messages).
// Update rows if requested
bool showNotificationArea(bool show, Window* wnd, NamedList* upd = 0);
// Update rows if requested. Add/remove tray notification/info icon
bool showNotificationArea(bool show, Window* wnd, NamedList* upd = 0,
const char* notif = "notification");
// Show a roster change or failure notification
void showUserRosterNotification(ClientAccount* a, const String& oper,
Message& msg, const String& contactUri = String::empty(),
bool newContact = true);
// Handle actions from notification area. Return true if handled
bool handleNotificationAreaAction(const String& action, Window* wnd);
// Save a contact to config. Save chat rooms if the contact is a chat room