diff --git a/application/views/RosterListView.cpp b/application/views/RosterListView.cpp index 7bb797c..84acad2 100644 --- a/application/views/RosterListView.cpp +++ b/application/views/RosterListView.cpp @@ -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(item1); + RosterItem* roster2 = dynamic_cast(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(item1); + RosterItem* roster2 = dynamic_cast(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); } diff --git a/application/views/RosterListView.h b/application/views/RosterListView.h index 233eeab..59bc85c 100644 --- a/application/views/RosterListView.h +++ b/application/views/RosterListView.h @@ -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(); diff --git a/application/views/RosterView.cpp b/application/views/RosterView.cpp index 0a2f46a..05b6565 100644 --- a/application/views/RosterView.cpp +++ b/application/views/RosterView.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #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) { diff --git a/application/views/RosterView.h b/application/views/RosterView.h index 1f0503d..dd045ca 100644 --- a/application/views/RosterView.h +++ b/application/views/RosterView.h @@ -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 diff --git a/application/windows/RosterEditWindow.cpp b/application/windows/RosterEditWindow.cpp index fccd862..fcc7c13 100644 --- a/application/windows/RosterEditWindow.cpp +++ b/application/windows/RosterEditWindow.cpp @@ -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. - BMessage* request = new BMessage(IM_MESSAGE); - request->AddInt32("im_what", IM_GET_EXTENDED_CONTACT_INFO); - request->AddString("user_id", user->GetId()); - user->GetProtocolLooper()->PostMessage(request); + // 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_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; diff --git a/application/windows/RosterWindow.cpp b/application/windows/RosterWindow.cpp index 9b40a81..f836fa2 100644 --- a/application/windows/RosterWindow.cpp +++ b/application/windows/RosterWindow.cpp @@ -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; }