Allow selection of non-contacts in roster windows
Windows using RosterView (like for the invitiation/new chat dialogues) have a search-box for filtering between contacts. This allows the user to type a user ID into this search-box that isn't a contact's ID, which can then be selected as the user. This makes common operations (inviting a user/adding a new contact) a little easier.
This commit is contained in:
parent
e33dd92375
commit
37453ba2af
|
@ -39,24 +39,36 @@ const int32 kGetInfo = 'GINF';
|
||||||
static int
|
static int
|
||||||
compare_by_name(const void* _item1, const void* _item2)
|
compare_by_name(const void* _item1, const void* _item2)
|
||||||
{
|
{
|
||||||
RosterItem* item1 = *(RosterItem**)_item1;
|
BListItem* item1 = *(BListItem**)_item1;
|
||||||
RosterItem* item2 = *(RosterItem**)_item2;
|
BListItem* item2 = *(BListItem**)_item2;
|
||||||
|
RosterItem* roster1 = dynamic_cast<RosterItem*>(item1);
|
||||||
|
RosterItem* roster2 = dynamic_cast<RosterItem*>(item2);
|
||||||
|
|
||||||
return strcasecmp(item1->GetContact()->GetName().String(),
|
if (roster1 == NULL && roster2 == NULL)
|
||||||
item2->GetContact()->GetName().String());
|
return 0;
|
||||||
|
if (roster1 == NULL)
|
||||||
|
return 1;
|
||||||
|
if (roster2 == NULL)
|
||||||
|
return -1;
|
||||||
|
return strcasecmp(roster1->GetContact()->GetName().String(),
|
||||||
|
roster2->GetContact()->GetName().String());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compare_by_status(const void* _item1, const void* _item2)
|
compare_by_status(const void* _item1, const void* _item2)
|
||||||
{
|
{
|
||||||
RosterItem* item1 = *(RosterItem**)_item1;
|
BListItem* item1 = *(RosterItem**)_item1;
|
||||||
RosterItem* item2 = *(RosterItem**)_item2;
|
BListItem* item2 = *(RosterItem**)_item2;
|
||||||
|
RosterItem* roster1 = dynamic_cast<RosterItem*>(item1);
|
||||||
|
RosterItem* roster2 = dynamic_cast<RosterItem*>(item2);
|
||||||
|
|
||||||
if (item1->Status() < item2->Status())
|
if (roster1 == NULL && roster2 == NULL)
|
||||||
|
return 0;
|
||||||
|
if (roster1 == NULL || roster1->Status() < roster2->Status())
|
||||||
return 1;
|
return 1;
|
||||||
if (item1->Status() > item2->Status())
|
if (roster2 == NULL || roster1->Status() > roster2->Status())
|
||||||
return 2;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +236,7 @@ RosterListView::Draw(BRect updateRect)
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RosterListView::AddItem(RosterItem* item)
|
RosterListView::AddItem(BListItem* item)
|
||||||
{
|
{
|
||||||
item->Deselect();
|
item->Deselect();
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
@ -235,11 +247,11 @@ RosterListView::AddItem(RosterItem* item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
bool
|
||||||
RosterListView::RemoveItem(RosterItem* item)
|
RosterListView::RemoveItem(BListItem* item)
|
||||||
{
|
{
|
||||||
item->Deselect();
|
item->Deselect();
|
||||||
BListView::RemoveItem(item);
|
return BListView::RemoveItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ public:
|
||||||
virtual void Draw(BRect updateRect);
|
virtual void Draw(BRect updateRect);
|
||||||
virtual void AttachedToWindow();
|
virtual void AttachedToWindow();
|
||||||
|
|
||||||
bool AddItem(RosterItem* item);
|
virtual bool AddItem(BListItem* item);
|
||||||
void RemoveItem(RosterItem* item);
|
virtual bool RemoveItem(BListItem* item);
|
||||||
RosterItem* RosterItemAt(int32 index);
|
RosterItem* RosterItemAt(int32 index);
|
||||||
|
|
||||||
void Sort();
|
void Sort();
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <LayoutBuilder.h>
|
#include <LayoutBuilder.h>
|
||||||
#include <Notification.h>
|
#include <Notification.h>
|
||||||
#include <ScrollView.h>
|
#include <ScrollView.h>
|
||||||
|
#include <StringItem.h>
|
||||||
|
|
||||||
#include "AppMessages.h"
|
#include "AppMessages.h"
|
||||||
#include "AppPreferences.h"
|
#include "AppPreferences.h"
|
||||||
|
@ -36,7 +37,9 @@ RosterView::RosterView(const char* title, Server* server, bigtime_t account)
|
||||||
:
|
:
|
||||||
BGroupView(title, B_VERTICAL, B_USE_DEFAULT_SPACING),
|
BGroupView(title, B_VERTICAL, B_USE_DEFAULT_SPACING),
|
||||||
fAccount(-1),
|
fAccount(-1),
|
||||||
fServer(server)
|
fServer(server),
|
||||||
|
fManualItem(new BStringItem("")),
|
||||||
|
fManualStr("Select user %user%" B_UTF8_ELLIPSIS)
|
||||||
{
|
{
|
||||||
fSearchBox = new BTextControl("searchBox", "", "",
|
fSearchBox = new BTextControl("searchBox", "", "",
|
||||||
new BMessage(kSearchContact));
|
new BMessage(kSearchContact));
|
||||||
|
@ -80,6 +83,18 @@ RosterView::MessageReceived(BMessage* message)
|
||||||
fListView->AddItem(item);
|
fListView->AddItem(item);
|
||||||
UpdateListItem(item);
|
UpdateListItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If view has specific account selected, we want the user to be
|
||||||
|
// able to select non-contacts of that protocol
|
||||||
|
if (fAccount != - 1 && strcmp(fSearchBox->Text(), "") != 0) {
|
||||||
|
BString label = fManualStr;
|
||||||
|
label.ReplaceAll("%user%", fSearchBox->Text());
|
||||||
|
|
||||||
|
fManualItem->SetText(label.String());
|
||||||
|
fListView->AddItem(fManualItem);
|
||||||
|
}
|
||||||
|
else if (fListView->HasItem(fManualItem))
|
||||||
|
fListView->RemoveItem(fManualItem);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IM_MESSAGE:
|
case IM_MESSAGE:
|
||||||
|
@ -133,9 +148,6 @@ RosterView::ImMessage(BMessage* msg)
|
||||||
|
|
||||||
UpdateListItem(rosterItem);
|
UpdateListItem(rosterItem);
|
||||||
|
|
||||||
// Sort list view again
|
|
||||||
fListView->Sort();
|
|
||||||
|
|
||||||
// Check if the user want the notification
|
// Check if the user want the notification
|
||||||
if (!AppPreferences::Item()->NotifyContactStatus)
|
if (!AppPreferences::Item()->NotifyContactStatus)
|
||||||
break;
|
break;
|
||||||
|
@ -224,6 +236,7 @@ RosterView::SetInvocationMessage(BMessage* msg)
|
||||||
fListView->SetInvocationMessage(msg);
|
fListView->SetInvocationMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RosterView::SetAccount(bigtime_t instance_id)
|
RosterView::SetAccount(bigtime_t instance_id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "Server.h"
|
#include "Server.h"
|
||||||
|
|
||||||
|
class BStringItem;
|
||||||
class BTextControl;
|
class BTextControl;
|
||||||
class RosterItem;
|
class RosterItem;
|
||||||
class RosterListView;
|
class RosterListView;
|
||||||
|
@ -33,6 +34,10 @@ public:
|
||||||
void SetInvocationMessage(BMessage* msg);
|
void SetInvocationMessage(BMessage* msg);
|
||||||
|
|
||||||
void SetAccount(bigtime_t instance_id);
|
void SetAccount(bigtime_t instance_id);
|
||||||
|
void SetManualString(const char* text) { fManualStr = text; }
|
||||||
|
|
||||||
|
int64 GetAccount() { return fAccount; }
|
||||||
|
BTextControl* SearchBox() { return fSearchBox; }
|
||||||
|
|
||||||
void UpdateListItem(RosterItem* item);
|
void UpdateListItem(RosterItem* item);
|
||||||
|
|
||||||
|
@ -45,6 +50,9 @@ private:
|
||||||
RosterListView* fListView;
|
RosterListView* fListView;
|
||||||
BTextControl* fSearchBox;
|
BTextControl* fSearchBox;
|
||||||
bigtime_t fAccount;
|
bigtime_t fAccount;
|
||||||
|
|
||||||
|
BStringItem* fManualItem;
|
||||||
|
BString fManualStr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _ROSTER_VIEW_H
|
#endif // _ROSTER_VIEW_H
|
||||||
|
|
|
@ -41,6 +41,9 @@ const uint32 kEditMember = 'RWEM';
|
||||||
const uint32 kSelAccount = 'RWSA';
|
const uint32 kSelAccount = 'RWSA';
|
||||||
const uint32 kSelNoAccount = 'RWNA';
|
const uint32 kSelNoAccount = 'RWNA';
|
||||||
|
|
||||||
|
const char* kAddTitle = B_TRANSLATE("Adding contact");
|
||||||
|
const char* kEditTitle = B_TRANSLATE("Editing contact");
|
||||||
|
|
||||||
RosterEditWindow* RosterEditWindow::fInstance = NULL;
|
RosterEditWindow* RosterEditWindow::fInstance = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,6 +56,8 @@ RosterEditWindow::RosterEditWindow(Server* server)
|
||||||
{
|
{
|
||||||
fRosterView = new RosterView("buddyView", server);
|
fRosterView = new RosterView("buddyView", server);
|
||||||
fRosterView->SetInvocationMessage(new BMessage(kEditMember));
|
fRosterView->SetInvocationMessage(new BMessage(kEditMember));
|
||||||
|
fRosterView->SetManualString(BString("Add %user% as contact"
|
||||||
|
B_UTF8_ELLIPSIS));
|
||||||
|
|
||||||
fAccountField = new BMenuField("accountMenuField", NULL,
|
fAccountField = new BMenuField("accountMenuField", NULL,
|
||||||
new AccountsMenu("accountMenu", BMessage(kSelAccount),
|
new AccountsMenu("accountMenu", BMessage(kSelAccount),
|
||||||
|
@ -128,26 +133,54 @@ RosterEditWindow::MessageReceived(BMessage* message)
|
||||||
|
|
||||||
int index = message->FindInt32("index");
|
int index = message->FindInt32("index");
|
||||||
RosterItem* ritem = fRosterView->ListView()->RosterItemAt(index);
|
RosterItem* ritem = fRosterView->ListView()->RosterItemAt(index);
|
||||||
if (ritem == NULL)
|
const char* search = fRosterView->SearchBox()->Text();
|
||||||
return;
|
User* user;
|
||||||
|
BString user_id;
|
||||||
|
int64 instance;
|
||||||
|
|
||||||
User* user = ritem->GetContact();
|
if (ritem != NULL) {
|
||||||
fEditingUser.SetTo(user->GetId().String());
|
user = ritem->GetContact();
|
||||||
|
user_id = user->GetId();
|
||||||
|
instance = user->GetProtocolLooper()->GetInstance();
|
||||||
|
}
|
||||||
|
else if (search != NULL) {
|
||||||
|
user_id = search;
|
||||||
|
instance = fRosterView->GetAccount();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
fEditingUser.SetTo(user_id.String());
|
||||||
|
|
||||||
// The response IM_EXTENDED_CONTACT_INFO is used to populate the
|
// The response IM_EXTENDED_CONTACT_INFO is used to populate the
|
||||||
// TemplateWindow.
|
// TemplateWindow― if we're editing a pre-existing contact
|
||||||
|
if (ritem != NULL) {
|
||||||
|
user = ritem->GetContact();
|
||||||
BMessage* request = new BMessage(IM_MESSAGE);
|
BMessage* request = new BMessage(IM_MESSAGE);
|
||||||
request->AddInt32("im_what", IM_GET_EXTENDED_CONTACT_INFO);
|
request->AddInt32("im_what", IM_GET_EXTENDED_CONTACT_INFO);
|
||||||
request->AddString("user_id", user->GetId());
|
request->AddString("user_id", user_id);
|
||||||
user->GetProtocolLooper()->PostMessage(request);
|
user->GetProtocolLooper()->PostMessage(request);
|
||||||
|
}
|
||||||
|
|
||||||
BMessage* edit = new BMessage(IM_MESSAGE);
|
BMessage* edit = new BMessage(IM_MESSAGE);
|
||||||
edit->AddInt32("im_what", IM_CONTACT_LIST_EDIT_CONTACT);
|
edit->AddInt32("im_what", IM_CONTACT_LIST_EDIT_CONTACT);
|
||||||
|
|
||||||
|
const char* title;
|
||||||
|
if (ritem == NULL)
|
||||||
|
title = kAddTitle;
|
||||||
|
else
|
||||||
|
title = kEditTitle;
|
||||||
|
|
||||||
fEditingWindow =
|
fEditingWindow =
|
||||||
new TemplateWindow(B_TRANSLATE("Editing contact"), "roster",
|
new TemplateWindow(title, "roster",
|
||||||
edit, fServer, user->GetProtocolLooper()->GetInstance());
|
edit, fServer, instance);
|
||||||
fEditingWindow->Show();
|
fEditingWindow->Show();
|
||||||
|
|
||||||
|
if (ritem == NULL) {
|
||||||
|
BMessage* idMsg = new BMessage(IM_MESSAGE);
|
||||||
|
idMsg->AddString("user_id", user_id);
|
||||||
|
fEditingWindow->PostMessage(idMsg);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kAddMember:
|
case kAddMember:
|
||||||
|
@ -155,7 +188,7 @@ RosterEditWindow::MessageReceived(BMessage* message)
|
||||||
BMessage* add = new BMessage(IM_MESSAGE);
|
BMessage* add = new BMessage(IM_MESSAGE);
|
||||||
add->AddInt32("im_what", IM_CONTACT_LIST_ADD_CONTACT);
|
add->AddInt32("im_what", IM_CONTACT_LIST_ADD_CONTACT);
|
||||||
TemplateWindow* win =
|
TemplateWindow* win =
|
||||||
new TemplateWindow(B_TRANSLATE("Adding contact"), "roster",
|
new TemplateWindow(B_TRANSLATE(kAddTitle), "roster",
|
||||||
add, fServer);
|
add, fServer);
|
||||||
win->Show();
|
win->Show();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -94,14 +94,27 @@ RosterWindow::MessageReceived(BMessage* message)
|
||||||
{
|
{
|
||||||
int index = message->FindInt32("index");
|
int index = message->FindInt32("index");
|
||||||
RosterItem* ritem = fRosterView->ListView()->RosterItemAt(index);
|
RosterItem* ritem = fRosterView->ListView()->RosterItemAt(index);
|
||||||
|
const char* search = fRosterView->SearchBox()->Text();
|
||||||
|
BString user_id;
|
||||||
|
int64 instance;
|
||||||
|
|
||||||
if (ritem == NULL)
|
if (ritem != NULL) {
|
||||||
|
User* user = ritem->GetContact();
|
||||||
|
user_id = user->GetId();
|
||||||
|
instance = user->GetProtocolLooper()->GetInstance();
|
||||||
|
}
|
||||||
|
else if (search != NULL) {
|
||||||
|
user_id = search;
|
||||||
|
instance = fRosterView->GetAccount();
|
||||||
|
}
|
||||||
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
User* user = ritem->GetContact();
|
User* user = ritem->GetContact();
|
||||||
fMessage->AddString("user_id", user->GetId());
|
fMessage->AddString("user_id", user_id);
|
||||||
fMessage->AddInt64("instance", user->GetProtocolLooper()->GetInstance());
|
fMessage->AddInt64("instance", instance);
|
||||||
fTarget->SendMessage(fMessage);
|
fTarget->SendMessage(fMessage);
|
||||||
|
fMessage->PrintToStream();
|
||||||
PostMessage(B_QUIT_REQUESTED);
|
PostMessage(B_QUIT_REQUESTED);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Ŝarĝante…
Reference in New Issue