2010-05-07 04:47:10 -05:00
|
|
|
/*
|
|
|
|
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
|
|
|
*/
|
|
|
|
|
2012-05-28 19:44:02 -05:00
|
|
|
#include "RosterListView.h"
|
2010-05-07 04:47:10 -05:00
|
|
|
|
|
|
|
#include <Looper.h>
|
|
|
|
#include <MenuItem.h>
|
|
|
|
#include <PopUpMenu.h>
|
|
|
|
#include <SeparatorItem.h>
|
|
|
|
|
2012-05-28 19:44:02 -05:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
2021-05-23 15:10:14 -05:00
|
|
|
#include "UserInfoWindow.h"
|
2021-05-23 14:39:07 -05:00
|
|
|
#include "Contact.h"
|
2010-05-07 04:47:10 -05:00
|
|
|
#include "RosterItem.h"
|
|
|
|
|
|
|
|
const int32 kAddPeople = 'ADPL';
|
2012-09-28 16:19:24 -05:00
|
|
|
const int32 kSendFile = 'SDFL';
|
|
|
|
const int32 kShowLogs = 'SHLG';
|
|
|
|
const int32 kStartConv = 'SRCV';
|
|
|
|
const int32 kGetInfo = 'GINF';
|
2010-05-07 04:47:10 -05:00
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
compare_by_name(const void* _item1, const void* _item2)
|
|
|
|
{
|
|
|
|
RosterItem* item1 = *(RosterItem**)_item1;
|
|
|
|
RosterItem* item2 = *(RosterItem**)_item2;
|
|
|
|
|
2021-05-23 14:39:07 -05:00
|
|
|
return strcasecmp(item1->GetContact()->GetName().String(),
|
|
|
|
item2->GetContact()->GetName().String());
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
compare_by_status(const void* _item1, const void* _item2)
|
|
|
|
{
|
|
|
|
RosterItem* item1 = *(RosterItem**)_item1;
|
|
|
|
RosterItem* item2 = *(RosterItem**)_item2;
|
|
|
|
|
|
|
|
if (item1->Status() < item2->Status())
|
|
|
|
return 1;
|
|
|
|
if (item1->Status() > item2->Status())
|
|
|
|
return 2;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RosterListView::RosterListView(const char* name)
|
2012-05-15 11:48:53 -05:00
|
|
|
: BOutlineListView(name, B_SINGLE_SELECTION_LIST,
|
|
|
|
B_WILL_DRAW | B_FRAME_EVENTS |
|
2010-05-07 04:47:10 -05:00
|
|
|
B_NAVIGABLE | B_FULL_UPDATE_ON_RESIZE),
|
|
|
|
fPrevItem(NULL)
|
|
|
|
{
|
|
|
|
// Context menu
|
2012-03-11 10:11:29 -05:00
|
|
|
fPopUp = new BPopUpMenu("contextMenu", false, false);
|
2012-09-28 16:19:24 -05:00
|
|
|
BMenuItem* item = NULL;
|
|
|
|
|
|
|
|
fPopUp->AddItem(new BMenuItem("Start a Conversation", new BMessage(kStartConv)));
|
|
|
|
item = new BMenuItem("Send a File", new BMessage(kSendFile));
|
|
|
|
item->SetEnabled(false);
|
|
|
|
fPopUp->AddItem(item);
|
|
|
|
|
|
|
|
fPopUp->AddItem(new BSeparatorItem());
|
|
|
|
|
2012-03-11 10:11:29 -05:00
|
|
|
fPopUp->AddItem(new BMenuItem("Get Informations", new BMessage(kGetInfo)));
|
2012-09-28 16:19:24 -05:00
|
|
|
|
|
|
|
item = new BMenuItem("Show Logs", new BMessage(kShowLogs));
|
|
|
|
item->SetEnabled(false);
|
|
|
|
fPopUp->AddItem(item);
|
|
|
|
|
2010-05-07 04:47:10 -05:00
|
|
|
fPopUp->AddItem(new BSeparatorItem());
|
2012-09-28 16:19:24 -05:00
|
|
|
|
|
|
|
item = new BMenuItem("Add to Address Book", new BMessage(kAddPeople));
|
|
|
|
item->SetEnabled(false);
|
|
|
|
fPopUp->AddItem(item);
|
|
|
|
|
2010-05-07 04:47:10 -05:00
|
|
|
fPopUp->SetTargetForItems(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// #pragama mark -
|
|
|
|
|
|
|
|
|
2012-03-11 10:11:29 -05:00
|
|
|
void
|
|
|
|
RosterListView::AttachedToWindow()
|
|
|
|
{
|
|
|
|
fPopUp->SetTargetForItems(this);
|
|
|
|
SetTarget(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-07 04:47:10 -05:00
|
|
|
void
|
|
|
|
RosterListView::MessageReceived(BMessage* msg)
|
|
|
|
{
|
2012-10-01 07:29:15 -05:00
|
|
|
BListItem* item = ItemAt(CurrentSelection());
|
2012-09-28 16:19:24 -05:00
|
|
|
RosterItem* ritem = reinterpret_cast<RosterItem*>(item);
|
|
|
|
|
2010-05-07 04:47:10 -05:00
|
|
|
switch (msg->what) {
|
|
|
|
case kGetInfo:
|
2012-03-11 10:11:29 -05:00
|
|
|
{
|
|
|
|
if (ritem == NULL)
|
|
|
|
return;
|
|
|
|
|
2021-05-23 14:39:07 -05:00
|
|
|
_InfoWindow(ritem->GetContact());
|
2010-05-07 04:47:10 -05:00
|
|
|
break;
|
2012-03-11 10:11:29 -05:00
|
|
|
}
|
2012-09-28 16:19:24 -05:00
|
|
|
|
|
|
|
case kStartConv:
|
|
|
|
{
|
|
|
|
if (ritem == NULL)
|
|
|
|
return;
|
2021-05-24 01:47:21 -05:00
|
|
|
// Contact* link = ritem->GetContact();
|
|
|
|
// link->ShowWindow(false, true);
|
2012-09-28 16:19:24 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-05-16 16:02:50 -05:00
|
|
|
default:
|
|
|
|
BListView::MessageReceived(msg);
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
RosterListView::MouseMoved(BPoint where, uint32 code, const BMessage* msg)
|
|
|
|
{
|
|
|
|
BListView::MouseMoved(where, code, msg);
|
|
|
|
return;
|
|
|
|
|
|
|
|
switch (code) {
|
|
|
|
case B_INSIDE_VIEW:
|
|
|
|
{
|
|
|
|
// Mouse cursor is inside this view, hide last item's popup
|
|
|
|
// and show current item's popup
|
|
|
|
BListItem* item = ItemAt(IndexOf(where));
|
|
|
|
RosterItem* ritem = reinterpret_cast<RosterItem*>(item);
|
|
|
|
|
|
|
|
if (ritem == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Hide previous item's popup
|
|
|
|
if ((fPrevItem != NULL) && (fPrevItem != ritem))
|
2021-05-23 14:39:07 -05:00
|
|
|
fPrevItem->GetContact()->HidePopUp();
|
2010-05-07 04:47:10 -05:00
|
|
|
|
|
|
|
// Show current item's popup
|
2021-05-23 14:39:07 -05:00
|
|
|
ritem->GetContact()->ShowPopUp(ConvertToScreen(where));
|
2010-05-07 04:47:10 -05:00
|
|
|
|
|
|
|
// This will be the previous item
|
|
|
|
fPrevItem = ritem;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case B_EXITED_VIEW:
|
|
|
|
// Mouse cursor leaved this view, hide last item's popup
|
|
|
|
if (fPrevItem != NULL)
|
2021-05-23 14:39:07 -05:00
|
|
|
fPrevItem->GetContact()->HidePopUp();
|
2010-05-07 04:47:10 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
RosterListView::MouseDown(BPoint where)
|
|
|
|
{
|
|
|
|
BMessage* message = Looper()->CurrentMessage();
|
|
|
|
|
|
|
|
int32 buttons = 0;
|
|
|
|
(void)message->FindInt32("buttons", &buttons);
|
|
|
|
|
|
|
|
if (buttons == B_SECONDARY_MOUSE_BUTTON) {
|
|
|
|
int32 index = IndexOf(where);
|
|
|
|
if (index >= 0) {
|
|
|
|
// Select list item
|
|
|
|
Select(index);
|
|
|
|
|
|
|
|
// Show context menu if right button is clicked
|
2012-03-11 10:11:29 -05:00
|
|
|
(void)fPopUp->Go(ConvertToScreen(where), true, true, false);
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
2012-03-11 10:11:29 -05:00
|
|
|
} else {
|
2010-05-07 04:47:10 -05:00
|
|
|
// Call original MouseDown()
|
|
|
|
BListView::MouseDown(where);
|
2012-03-11 10:11:29 -05:00
|
|
|
}
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
RosterListView::Draw(BRect updateRect)
|
|
|
|
{
|
|
|
|
int32 count = CountItems();
|
|
|
|
if (count == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
BRect itemFrame(0, 0, Bounds().right, -1);
|
|
|
|
for (int32 i = 0; i < count; i++) {
|
|
|
|
BListItem* item = ItemAt(i);
|
|
|
|
RosterItem* rosterItem = reinterpret_cast<RosterItem*>(item);
|
|
|
|
|
|
|
|
if (!rosterItem->IsVisible())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
itemFrame.bottom = itemFrame.top + ceilf(item->Height()) - 1;
|
|
|
|
|
|
|
|
if (itemFrame.Intersects(updateRect))
|
|
|
|
rosterItem->DrawItem(this, itemFrame);
|
|
|
|
|
|
|
|
itemFrame.top = itemFrame.bottom + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
RosterListView::Sort()
|
|
|
|
{
|
|
|
|
SortItems(compare_by_name);
|
|
|
|
}
|
2012-03-11 10:11:29 -05:00
|
|
|
|
|
|
|
|
|
|
|
void
|
2021-05-23 14:39:07 -05:00
|
|
|
RosterListView::_InfoWindow(Contact* linker)
|
2012-03-11 10:11:29 -05:00
|
|
|
{
|
2021-05-23 15:10:14 -05:00
|
|
|
UserInfoWindow* win = new UserInfoWindow(linker);
|
2012-03-11 10:11:29 -05:00
|
|
|
win->Show();
|
|
|
|
}
|