9d72c53dd9
Most of RosterWindow's special functions have been split into a special BGroupView (including both the roster search-box and roster list), RosterView. This will give some more flexibility in other uses of the roster list. In addition, RosterViews can be tied to a specific account by its looper's instance ID, allowing it to either show all contacts (globally; if the ID is set to -1) or only those of the specified account. This can be useful, for example, when inviting contacts to a room― you can only invite contacts that use the same protocol, and are associated with your account, so showing all contacts doesn't make sense. The SearchBarTextControl class was removed, as it isn't particularly necessary.
244 lines
5.4 KiB
C++
244 lines
5.4 KiB
C++
/*
|
|
* Copyright 2009-2011, Andrea Anzani. All rights reserved.
|
|
* Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
|
|
* Copyright 2021, Jaidyn Levesque. All rights reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Andrea Anzani, andrea.anzani@gmail.com
|
|
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
|
* Jaidyn Levesque, jadedctrl@teknik.io
|
|
*/
|
|
|
|
#include "RosterView.h"
|
|
|
|
#include <LayoutBuilder.h>
|
|
#include <Notification.h>
|
|
#include <ScrollView.h>
|
|
|
|
#include "CayaMessages.h"
|
|
#include "CayaPreferences.h"
|
|
#include "CayaProtocolMessages.h"
|
|
#include "RosterItem.h"
|
|
#include "RosterListView.h"
|
|
|
|
|
|
const uint32 kSearchContact = 'RWSC';
|
|
|
|
|
|
RosterView::RosterView(const char* title, Server* server, bigtime_t account)
|
|
:
|
|
BGroupView(title, B_VERTICAL, B_USE_DEFAULT_SPACING),
|
|
fAccount(-1),
|
|
fServer(server)
|
|
{
|
|
fSearchBox = new BTextControl("searchBox", "", "",
|
|
new BMessage(kSearchContact));
|
|
fSearchBox->SetModificationMessage(new BMessage(kSearchContact));
|
|
|
|
|
|
fListView = new RosterListView("buddyView");
|
|
BScrollView* scrollView = new BScrollView("scrollview", fListView,
|
|
B_WILL_DRAW, false, true);
|
|
|
|
BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f)
|
|
.AddGroup(B_VERTICAL)
|
|
.SetInsets(5, 5, 5, 10)
|
|
.Add(fSearchBox)
|
|
.Add(scrollView)
|
|
.End()
|
|
.End();
|
|
|
|
SetAccount(account);
|
|
}
|
|
|
|
|
|
void
|
|
RosterView::MessageReceived(BMessage* message)
|
|
{
|
|
switch (message->what) {
|
|
case kSearchContact:
|
|
{
|
|
RosterMap map = _RosterMap();
|
|
for (uint32 i = 0; i < map.CountItems(); i++) {
|
|
Contact* linker = map.ValueAt(i);
|
|
RosterItem* item = linker->GetRosterItem();
|
|
|
|
// If the search filter has been deleted show all the items,
|
|
// otherwise remove the item in order to show only items
|
|
// that matches the search criteria
|
|
if (strcmp(fSearchBox->Text(), "") == 0)
|
|
fListView->AddRosterItem(item);
|
|
else if (linker->GetName().IFindFirst(fSearchBox->Text()) == B_ERROR)
|
|
fListView->RemoveItem(item);
|
|
else
|
|
fListView->AddRosterItem(item);
|
|
UpdateListItem(item);
|
|
}
|
|
break;
|
|
}
|
|
case IM_MESSAGE:
|
|
ImMessage(message);
|
|
break;
|
|
|
|
default:
|
|
BGroupView::MessageReceived(message);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
RosterView::ImMessage(BMessage* msg)
|
|
{
|
|
int32 im_what = msg->FindInt32("im_what");
|
|
switch (im_what) {
|
|
case IM_STATUS_SET:
|
|
{
|
|
int32 status;
|
|
int64 instance;
|
|
BString user_id = msg->FindString("user_id");
|
|
if (msg->FindInt32("status", &status) != B_OK
|
|
|| msg->FindInt64("instance", &instance) != B_OK
|
|
|| user_id.IsEmpty() == true)
|
|
return;
|
|
|
|
Contact* contact = fServer->ContactById(user_id, instance);
|
|
if (contact == NULL)
|
|
return;
|
|
|
|
RosterItem* rosterItem = contact->GetRosterItem();
|
|
|
|
if (rosterItem) {
|
|
UpdateListItem(rosterItem);
|
|
|
|
// Add or remove item
|
|
switch (status) {
|
|
/*case CAYA_OFFLINE:
|
|
// By default offline contacts are hidden
|
|
if (!CayaPreferences::Item()->HideOffline)
|
|
break;
|
|
if (HasItem(rosterItem))
|
|
RemoveItem(rosterItem);
|
|
return;*/
|
|
default:
|
|
// Add item because it has a non-offline status
|
|
fListView->AddRosterItem(rosterItem);
|
|
break;
|
|
}
|
|
|
|
UpdateListItem(rosterItem);
|
|
|
|
// Sort list view again
|
|
fListView->Sort();
|
|
|
|
// Check if the user want the notification
|
|
if (!CayaPreferences::Item()->NotifyContactStatus)
|
|
break;
|
|
|
|
switch (status) {
|
|
case CAYA_ONLINE:
|
|
case CAYA_OFFLINE:
|
|
// Notify when contact is online or offline
|
|
if (status == CAYA_ONLINE) {
|
|
BString message;
|
|
message << rosterItem->GetContact()->GetName();
|
|
|
|
if (status == CAYA_ONLINE)
|
|
message << " is available!";
|
|
else
|
|
message << " is offline!";
|
|
|
|
BNotification notification(B_INFORMATION_NOTIFICATION);
|
|
notification.SetGroup(BString("Caya"));
|
|
notification.SetTitle(BString("Presence"));
|
|
notification.SetIcon(rosterItem->Bitmap());
|
|
notification.SetContent(message);
|
|
notification.Send();
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case IM_AVATAR_SET:
|
|
case IM_CONTACT_INFO:
|
|
case IM_EXTENDED_CONTACT_INFO:
|
|
{
|
|
int32 status = -1;
|
|
int64 instance;
|
|
BString user_id = msg->FindString("user_id");
|
|
if (msg->FindInt32("status", &status) != B_OK
|
|
|| msg->FindInt64("instance", &instance) != B_OK
|
|
|| user_id.IsEmpty() == true)
|
|
return;
|
|
|
|
Contact* contact = fServer->ContactById(user_id, instance);
|
|
if (contact == NULL)
|
|
return;
|
|
|
|
RosterItem* rosterItem = contact->GetRosterItem();
|
|
if (rosterItem)
|
|
UpdateListItem(rosterItem);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
RosterView::AttachedToWindow()
|
|
{
|
|
fSearchBox->SetTarget(this);
|
|
fSearchBox->MakeFocus(true);
|
|
}
|
|
|
|
|
|
void
|
|
RosterView::SetInvocationMessage(BMessage* msg)
|
|
{
|
|
fListView->SetInvocationMessage(msg);
|
|
}
|
|
|
|
|
|
void
|
|
RosterView::SetAccount(bigtime_t instance_id)
|
|
{
|
|
fAccount = instance_id;
|
|
RosterMap contacts = _RosterMap();
|
|
|
|
fListView->MakeEmpty();
|
|
for (int i = 0; i < contacts.CountItems(); i++)
|
|
fListView->AddRosterItem(contacts.ValueAt(i)->GetRosterItem());
|
|
}
|
|
|
|
|
|
void
|
|
RosterView::UpdateListItem(RosterItem* item)
|
|
{
|
|
if (fListView->HasItem(item))
|
|
fListView->InvalidateItem(fListView->IndexOf(item));
|
|
}
|
|
|
|
|
|
RosterListView*
|
|
RosterView::ListView()
|
|
{
|
|
return fListView;
|
|
}
|
|
|
|
|
|
RosterMap
|
|
RosterView::_RosterMap()
|
|
{
|
|
RosterMap contacts;
|
|
if (fAccount < 0)
|
|
contacts = fServer->Contacts();
|
|
else {
|
|
ProtocolLooper* looper = fServer->GetProtocolLooper(fAccount);
|
|
contacts = looper->Contacts();
|
|
}
|
|
return contacts;
|
|
}
|