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
|
||||
compare_by_name(const void* _item1, const void* _item2)
|
||||
{
|
||||
RosterItem* item1 = *(RosterItem**)_item1;
|
||||
RosterItem* item2 = *(RosterItem**)_item2;
|
||||
BListItem* item1 = *(BListItem**)_item1;
|
||||
BListItem* item2 = *(BListItem**)_item2;
|
||||
RosterItem* roster1 = dynamic_cast<RosterItem*>(item1);
|
||||
RosterItem* roster2 = dynamic_cast<RosterItem*>(item2);
|
||||
|
||||
return strcasecmp(item1->GetContact()->GetName().String(),
|
||||
item2->GetContact()->GetName().String());
|
||||
if (roster1 == NULL && roster2 == NULL)
|
||||
return 0;
|
||||
if (roster1 == NULL)
|
||||
return 1;
|
||||
if (roster2 == NULL)
|
||||
return -1;
|
||||
return strcasecmp(roster1->GetContact()->GetName().String(),
|
||||
roster2->GetContact()->GetName().String());
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
compare_by_status(const void* _item1, const void* _item2)
|
||||
{
|
||||
RosterItem* item1 = *(RosterItem**)_item1;
|
||||
RosterItem* item2 = *(RosterItem**)_item2;
|
||||
BListItem* item1 = *(RosterItem**)_item1;
|
||||
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;
|
||||
if (item1->Status() > item2->Status())
|
||||
return 2;
|
||||
if (roster2 == NULL || roster1->Status() > roster2->Status())
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -224,7 +236,7 @@ RosterListView::Draw(BRect updateRect)
|
|||
|
||||
|
||||
bool
|
||||
RosterListView::AddItem(RosterItem* item)
|
||||
RosterListView::AddItem(BListItem* item)
|
||||
{
|
||||
item->Deselect();
|
||||
bool ret = false;
|
||||
|
@ -235,11 +247,11 @@ RosterListView::AddItem(RosterItem* item)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
RosterListView::RemoveItem(RosterItem* item)
|
||||
bool
|
||||
RosterListView::RemoveItem(BListItem* item)
|
||||
{
|
||||
item->Deselect();
|
||||
BListView::RemoveItem(item);
|
||||
return BListView::RemoveItem(item);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ public:
|
|||
virtual void Draw(BRect updateRect);
|
||||
virtual void AttachedToWindow();
|
||||
|
||||
bool AddItem(RosterItem* item);
|
||||
void RemoveItem(RosterItem* item);
|
||||
virtual bool AddItem(BListItem* item);
|
||||
virtual bool RemoveItem(BListItem* item);
|
||||
RosterItem* RosterItemAt(int32 index);
|
||||
|
||||
void Sort();
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <LayoutBuilder.h>
|
||||
#include <Notification.h>
|
||||
#include <ScrollView.h>
|
||||
#include <StringItem.h>
|
||||
|
||||
#include "AppMessages.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),
|
||||
fAccount(-1),
|
||||
fServer(server)
|
||||
fServer(server),
|
||||
fManualItem(new BStringItem("")),
|
||||
fManualStr("Select user %user%" B_UTF8_ELLIPSIS)
|
||||
{
|
||||
fSearchBox = new BTextControl("searchBox", "", "",
|
||||
new BMessage(kSearchContact));
|
||||
|
@ -80,6 +83,18 @@ RosterView::MessageReceived(BMessage* message)
|
|||
fListView->AddItem(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;
|
||||
}
|
||||
case IM_MESSAGE:
|
||||
|
@ -133,9 +148,6 @@ RosterView::ImMessage(BMessage* msg)
|
|||
|
||||
UpdateListItem(rosterItem);
|
||||
|
||||
// Sort list view again
|
||||
fListView->Sort();
|
||||
|
||||
// Check if the user want the notification
|
||||
if (!AppPreferences::Item()->NotifyContactStatus)
|
||||
break;
|
||||
|
@ -224,6 +236,7 @@ RosterView::SetInvocationMessage(BMessage* msg)
|
|||
fListView->SetInvocationMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RosterView::SetAccount(bigtime_t instance_id)
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "Server.h"
|
||||
|
||||
class BStringItem;
|
||||
class BTextControl;
|
||||
class RosterItem;
|
||||
class RosterListView;
|
||||
|
@ -33,6 +34,10 @@ public:
|
|||
void SetInvocationMessage(BMessage* msg);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -45,6 +50,9 @@ private:
|
|||
RosterListView* fListView;
|
||||
BTextControl* fSearchBox;
|
||||
bigtime_t fAccount;
|
||||
|
||||
BStringItem* fManualItem;
|
||||
BString fManualStr;
|
||||
};
|
||||
|
||||
#endif // _ROSTER_VIEW_H
|
||||
|
|
|
@ -41,6 +41,9 @@ const uint32 kEditMember = 'RWEM';
|
|||
const uint32 kSelAccount = 'RWSA';
|
||||
const uint32 kSelNoAccount = 'RWNA';
|
||||
|
||||
const char* kAddTitle = B_TRANSLATE("Adding contact");
|
||||
const char* kEditTitle = B_TRANSLATE("Editing contact");
|
||||
|
||||
RosterEditWindow* RosterEditWindow::fInstance = NULL;
|
||||
|
||||
|
||||
|
@ -53,6 +56,8 @@ RosterEditWindow::RosterEditWindow(Server* server)
|
|||
{
|
||||
fRosterView = new RosterView("buddyView", server);
|
||||
fRosterView->SetInvocationMessage(new BMessage(kEditMember));
|
||||
fRosterView->SetManualString(BString("Add %user% as contact"
|
||||
B_UTF8_ELLIPSIS));
|
||||
|
||||
fAccountField = new BMenuField("accountMenuField", NULL,
|
||||
new AccountsMenu("accountMenu", BMessage(kSelAccount),
|
||||
|
@ -128,26 +133,54 @@ RosterEditWindow::MessageReceived(BMessage* message)
|
|||
|
||||
int index = message->FindInt32("index");
|
||||
RosterItem* ritem = fRosterView->ListView()->RosterItemAt(index);
|
||||
if (ritem == NULL)
|
||||
return;
|
||||
const char* search = fRosterView->SearchBox()->Text();
|
||||
User* user;
|
||||
BString user_id;
|
||||
int64 instance;
|
||||
|
||||
User* user = ritem->GetContact();
|
||||
fEditingUser.SetTo(user->GetId().String());
|
||||
if (ritem != NULL) {
|
||||
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
|
||||
// TemplateWindow.
|
||||
// TemplateWindow― if we're editing a pre-existing contact
|
||||
if (ritem != NULL) {
|
||||
user = ritem->GetContact();
|
||||
BMessage* request = new BMessage(IM_MESSAGE);
|
||||
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);
|
||||
}
|
||||
|
||||
BMessage* edit = new BMessage(IM_MESSAGE);
|
||||
edit->AddInt32("im_what", IM_CONTACT_LIST_EDIT_CONTACT);
|
||||
|
||||
const char* title;
|
||||
if (ritem == NULL)
|
||||
title = kAddTitle;
|
||||
else
|
||||
title = kEditTitle;
|
||||
|
||||
fEditingWindow =
|
||||
new TemplateWindow(B_TRANSLATE("Editing contact"), "roster",
|
||||
edit, fServer, user->GetProtocolLooper()->GetInstance());
|
||||
new TemplateWindow(title, "roster",
|
||||
edit, fServer, instance);
|
||||
fEditingWindow->Show();
|
||||
|
||||
if (ritem == NULL) {
|
||||
BMessage* idMsg = new BMessage(IM_MESSAGE);
|
||||
idMsg->AddString("user_id", user_id);
|
||||
fEditingWindow->PostMessage(idMsg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kAddMember:
|
||||
|
@ -155,7 +188,7 @@ RosterEditWindow::MessageReceived(BMessage* message)
|
|||
BMessage* add = new BMessage(IM_MESSAGE);
|
||||
add->AddInt32("im_what", IM_CONTACT_LIST_ADD_CONTACT);
|
||||
TemplateWindow* win =
|
||||
new TemplateWindow(B_TRANSLATE("Adding contact"), "roster",
|
||||
new TemplateWindow(B_TRANSLATE(kAddTitle), "roster",
|
||||
add, fServer);
|
||||
win->Show();
|
||||
break;
|
||||
|
|
|
@ -94,14 +94,27 @@ RosterWindow::MessageReceived(BMessage* message)
|
|||
{
|
||||
int index = message->FindInt32("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;
|
||||
|
||||
User* user = ritem->GetContact();
|
||||
fMessage->AddString("user_id", user->GetId());
|
||||
fMessage->AddInt64("instance", user->GetProtocolLooper()->GetInstance());
|
||||
fMessage->AddString("user_id", user_id);
|
||||
fMessage->AddInt64("instance", instance);
|
||||
fTarget->SendMessage(fMessage);
|
||||
fMessage->PrintToStream();
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
break;
|
||||
}
|
||||
|
|
Ŝarĝante…
Reference in New Issue