diff --git a/application/ChatWindow.cpp b/application/ChatWindow.cpp index 7d4fbe2..cb0973e 100644 --- a/application/ChatWindow.cpp +++ b/application/ChatWindow.cpp @@ -32,6 +32,7 @@ #include "CayaMessages.h" #include "CayaProtocolMessages.h" #include "CayaPreferences.h" +#include "ConversationView.h" #include "Conversation.h" #include "Contact.h" #include "EditingFilter.h" @@ -42,65 +43,22 @@ ChatWindow::ChatWindow(Conversation* cl) : - BWindow(BRect(200, 200, 500, 500), - cl->GetName().String(), B_TITLED_WINDOW, 0), - fConversation(cl), - fContact(cl->Users().ValueAt(0)) + BWindow(BRect(200, 200, 500, 500), "Chat", B_TITLED_WINDOW, 0) { - fMessageCount = 0; - - fReceiveView = new CayaRenderView("fReceiveView"); - BScrollView* scrollViewReceive = new BScrollView("scrollviewR", - fReceiveView, B_WILL_DRAW, false, true); + fChatView = new ConversationView(cl); fSendView = new BTextView("fReceiveView"); BScrollView* scrollViewSend = new BScrollView("scrollviewS", fSendView, B_WILL_DRAW, false, true); fSendView->SetWordWrap(true); + AddCommonFilter(new EditingFilter(fSendView)); fSendView->MakeFocus(true); - - fPersonalMessage = new BTextView("personalMessage", B_WILL_DRAW); - fPersonalMessage->SetExplicitAlignment( - BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE)); - - fPersonalMessage->SetText(fContact->GetNotifyPersonalStatus()); - fPersonalMessage->SetExplicitMaxSize(BSize(400, 200)); - fPersonalMessage->MakeEditable(false); - fPersonalMessage->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - - - fStatus = new BStringView("status", ""); - fStatus->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE)); - - fAvatar = new BitmapView("ContactIcon"); - fAvatar->SetExplicitMaxSize(BSize(50, 50)); - fAvatar->SetExplicitMinSize(BSize(50, 50)); - fAvatar->SetExplicitPreferredSize(BSize(50, 50)); - fAvatar->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_MIDDLE)); - fAvatar->SetBitmap(fContact->AvatarBitmap()); - - BBitmap* protocolBitmap = fContact->ProtocolBitmap(); - BitmapView* protocolView = new BitmapView("protocolView"); - protocolView->SetBitmap(protocolBitmap); - - BLayoutBuilder::Group<>(this, B_VERTICAL, 10) - .AddGroup(B_HORIZONTAL) - .Add(protocolView) - .Add(fPersonalMessage) - .Add(fAvatar) - .End() - .AddSplit(B_VERTICAL, 2.0f) - .Add(scrollViewReceive, 3) - .Add(scrollViewSend, 2) - .End() - .Add(fStatus, 4) - .SetInsets(5, 5, 5, 5); - - MoveTo(BAlert::AlertPosition(Bounds().Width(), Bounds().Height() / 2)); - - fSendView->MakeFocus(true); + BLayoutBuilder::Group<>(this, B_VERTICAL) + .Add(fChatView) + .Add(scrollViewSend) + .End(); } @@ -122,57 +80,25 @@ bool ChatWindow::QuitRequested() { BMessage msg(CAYA_CLOSE_CHAT_WINDOW); - msg.AddString("chat_id", fConversation->GetId()); - fConversation->Messenger().SendMessage(&msg); +// msg.AddString("chat_id", fConversation->GetId()); +// fConversation->Messenger().SendMessage(&msg); return false; } -void -ChatWindow::UpdateAvatar() -{ - if (fContact->AvatarBitmap() != NULL) { - LockLooper(); - fAvatar->SetBitmap(fContact->AvatarBitmap()); - UnlockLooper(); - } -} - - -void -ChatWindow::UpdatePersonalMessage() -{ - if (fContact->GetNotifyPersonalStatus() != NULL) { - LockLooper(); - fPersonalMessage->SetText(fContact->GetNotifyPersonalStatus()); - UnlockLooper(); - } -} - - void ChatWindow::MessageReceived(BMessage* message) { switch (message->what) { case CAYA_CHAT: - { - BString message = fSendView->Text(); - if (message == "") - return; - - fReceiveView->AppendOwnMessage(message.String()); - - BMessage msg(IM_MESSAGE); - msg.AddInt32("im_what", IM_SEND_MESSAGE); - msg.AddString("chat_id", fConversation->GetId()); - msg.AddString("body", message); - fConversation->ImMessage(&msg); - + message->PrintToStream(); + message->AddString("body", fSendView->Text()); + fChatView->MessageReceived(message); fSendView->SetText(""); break; - } + case IM_MESSAGE: - ImMessage(message); + fChatView->ImMessage(message); break; default: @@ -185,165 +111,28 @@ ChatWindow::MessageReceived(BMessage* message) void ChatWindow::ImMessage(BMessage* msg) { - int32 im_what = msg->FindInt32("im_what"); - - switch (im_what) { - case IM_MESSAGE_RECEIVED: - { - BString message = msg->FindString("body"); - BString id = msg->FindString("user_id"); - User* sender = fConversation->UserById(id); - BString uname = sender->GetName(); - - fReceiveView->AppendOtherMessage(uname.String(), message.String()); - - // Message received, clear status anyway - fStatus->SetText(""); - - if (IsActive()) break; - - fMessageCount++; - - // Mark unread window - if (CayaPreferences::Item()->MarkUnreadWindow) { - BString title = "["; - title << fMessageCount; - title << "] "; - title << uname; - SetTitle(title); - } - - // Check if the user want the notification - if (!CayaPreferences::Item()->NotifyNewMessage) - break; - - BString notify_message; - notify_message << "You've got "; - notify_message << fMessageCount; - if (fMessageCount==1) { - notify_message << " new message from "; - } else { - notify_message << " new messages from "; - }; - notify_message << uname; - - BNotification notification(B_INFORMATION_NOTIFICATION); - notification.SetGroup(BString("Caya")); - notification.SetTitle(BString("New message")); - notification.SetIcon(sender->AvatarBitmap()); - notification.SetContent(notify_message); - notification.SetMessageID(uname); - notification.Send(); - - break; - } - case IM_LOGS_RECEIVED: - { - BStringList logs; - if (msg->FindStrings("log", &logs) != B_OK) - return; - - for (int i = logs.CountStrings(); i >= 0; i--) - fReceiveView->AppendGenericMessage(logs.StringAt(i).String()); - - break; - } - case IM_CONTACT_STARTED_TYPING: - fStatus->SetText("Contact is typing..."); - break; - case IM_CONTACT_STOPPED_TYPING: - fStatus->SetText(""); - break; - case IM_CONTACT_GONE: - fStatus->SetText("Contact closed the chat window!"); - snooze(10000); - fStatus->SetText(""); - break; - default: - break; - } -} - - -void -ChatWindow::WindowActivated(bool active) -{ - SetTitle(fContact->GetName()); - fMessageCount=0; + fChatView->ImMessage(msg); } void ChatWindow::ObserveString(int32 what, BString str) { - switch (what) { - case STR_CONTACT_NAME: - if (Lock()) { - SetTitle(str); - Unlock(); - } - break; - case STR_PERSONAL_STATUS: - break; - } + fChatView->ObserveString(what, str); } void ChatWindow::ObservePointer(int32 what, void* ptr) { - switch (what) { - case PTR_AVATAR_BITMAP: - break; - } + fChatView->ObservePointer(what, ptr); } void ChatWindow::ObserveInteger(int32 what, int32 val) { - switch (what) { - case INT_CONTACT_STATUS: - if (Lock()) { - AppendStatus((CayaStatus)val); - Unlock(); - } - break; - } -} - - -void -ChatWindow::AppendStatus(CayaStatus status) -{ - BString message(fContact->GetName()); - - switch (status) { - case CAYA_ONLINE: - message << " is available"; - break; - case CAYA_AWAY: - message << " is away"; - break; - case CAYA_DO_NOT_DISTURB: - message << " is busy, please do not disturb!"; - break; - case CAYA_CUSTOM_STATUS: - message << " has set a custom status."; - break; - case CAYA_INVISIBLE: - message << " is invisible."; - break; - case CAYA_OFFLINE: - message << " is offline"; - break; - default: - break; - } - - fReceiveView->Append(message.String(), COL_TEXT, COL_TEXT, R_TEXT); - fReceiveView->Append("\n", COL_TEXT, COL_TEXT, R_TEXT); - fReceiveView->ScrollToSelection(); + fChatView->ObserveInteger(what, val); } @@ -358,3 +147,5 @@ ChatWindow::AvoidFocus(bool avoid) else SetFlags(Flags() &~ B_AVOID_FOCUS); } + + diff --git a/application/ChatWindow.h b/application/ChatWindow.h index 0a6a77a..d005139 100644 --- a/application/ChatWindow.h +++ b/application/ChatWindow.h @@ -15,6 +15,7 @@ class BitmapView; class Conversation; +class ConversationView; class CayaRenderView; class Contact; @@ -26,29 +27,18 @@ public: virtual void ShowWindow(); virtual void MessageReceived(BMessage* message); - void WindowActivated(bool active); virtual bool QuitRequested(); - void UpdateAvatar(); - void UpdatePersonalMessage(); void ImMessage(BMessage* msg); void ObserveString(int32 what, BString str); void ObservePointer(int32 what, void* ptr); void ObserveInteger(int32 what, int32 val); - void AppendStatus(CayaStatus status); void AvoidFocus(bool avoid); private: BTextView* fSendView; - Conversation* fConversation; - Contact* fContact; - CayaRenderView* fReceiveView; - BStringView* fStatus; - BTextView* fPersonalMessage; - BitmapView* fAvatar; - int32 fMessageCount; - + ConversationView* fChatView; }; #endif // _CHAT_WINDOW_H diff --git a/application/Makefile b/application/Makefile index b9ec14e..326b837 100644 --- a/application/Makefile +++ b/application/Makefile @@ -37,9 +37,9 @@ SRCS = \ application/AccountManager.cpp \ application/CayaProtocolAddOn.cpp \ application/CayaUtils.cpp \ - application/ChatWindow.cpp \ application/Contact.cpp \ application/Conversation.cpp \ + application/ChatWindow.cpp \ application/EditingFilter.cpp \ application/ImageCache.cpp \ application/Main.cpp \ @@ -65,6 +65,7 @@ SRCS = \ application/views/CayaRenderView.cpp \ application/views/ConversationItem.cpp \ application/views/ConversationListView.cpp \ + application/views/ConversationView.cpp \ application/views/NicknameTextControl.cpp \ application/views/ReplicantStatusView.cpp \ application/views/ReplicantMenuItem.cpp \ diff --git a/application/views/ConversationView.cpp b/application/views/ConversationView.cpp new file mode 100644 index 0000000..7c264b7 --- /dev/null +++ b/application/views/ConversationView.cpp @@ -0,0 +1,293 @@ +/* + * Copyright 2009-2011, Andrea Anzani. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Andrea Anzani, andrea.anzani@gmail.com + */ + +#include "ConversationView.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "CayaConstants.h" +#include "CayaMessages.h" +#include "CayaPreferences.h" +#include "CayaProtocolMessages.h" +#include "CayaRenderView.h" +#include "Contact.h" +#include "Conversation.h" +#include "EditingFilter.h" +#include "NotifyMessage.h" + + +ConversationView::ConversationView(Conversation* chat) + : + BGroupView("chatView", B_VERTICAL, B_USE_DEFAULT_SPACING), + fConversation(chat), + fContact(chat->Users().ValueAt(0)) +{ + fMessageCount = 0; + + fReceiveView = new CayaRenderView("fReceiveView"); + BScrollView* scrollViewReceive = new BScrollView("scrollviewR", + fReceiveView, B_WILL_DRAW, false, true); + + + fPersonalMessage = new BTextView("personalMessage", B_WILL_DRAW); + fPersonalMessage->SetExplicitAlignment( + BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE)); + + fPersonalMessage->SetText(""); + fPersonalMessage->SetExplicitMaxSize(BSize(400, 200)); + fPersonalMessage->MakeEditable(false); + fPersonalMessage->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + fStatus = new BStringView("status", ""); + fStatus->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE)); + + fAvatar = new BitmapView("ContactIcon"); + fAvatar->SetExplicitMaxSize(BSize(50, 50)); + fAvatar->SetExplicitMinSize(BSize(50, 50)); + fAvatar->SetExplicitPreferredSize(BSize(50, 50)); + fAvatar->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_MIDDLE)); + + fProtocolView = new BitmapView("protocolView"); + + BLayoutBuilder::Group<>(this, B_VERTICAL) + .AddGroup(B_HORIZONTAL) + .Add(fProtocolView) + .Add(fPersonalMessage) + .Add(fAvatar) + .End() + .Add(scrollViewReceive, 3) + .Add(fStatus, 4) + .SetInsets(5, 5, 5, 5); +} + + +bool +ConversationView::QuitRequested() +{ + BMessage msg(CAYA_CLOSE_CHAT_WINDOW); + msg.AddString("chat_id", fConversation->GetId()); + fConversation->Messenger().SendMessage(&msg); + return false; +} + + +Conversation* +ConversationView::GetConversation() +{ + return fConversation; +} + + +void +ConversationView::UpdateAvatar() +{ + if (fContact->AvatarBitmap() != NULL) + fAvatar->SetBitmap(fContact->AvatarBitmap()); +} + + +void +ConversationView::UpdatePersonalMessage() +{ + if (fContact->GetNotifyPersonalStatus() != NULL) + fPersonalMessage->SetText(fContact->GetNotifyPersonalStatus()); +} + + +void +ConversationView::MessageReceived(BMessage* message) +{ + switch (message->what) { + case CAYA_CHAT: + { + BString text = message->FindString("body"); + if (text == "") + return; + + fReceiveView->AppendOwnMessage(text.String()); + + BMessage msg(IM_MESSAGE); + msg.AddInt32("im_what", IM_SEND_MESSAGE); + msg.AddString("chat_id", fConversation->GetId()); + msg.AddString("body", text); + fConversation->ImMessage(&msg); + break; + } + case IM_MESSAGE: + ImMessage(message); + break; + + default: + BGroupView::MessageReceived(message); + break; + } +} + + +void +ConversationView::ImMessage(BMessage* msg) +{ + int32 im_what = msg->FindInt32("im_what"); + + switch (im_what) { + case IM_MESSAGE_RECEIVED: + { + BString message = msg->FindString("body"); + BString id = msg->FindString("user_id"); + User* sender = fConversation->UserById(id); + BString uname = sender->GetName(); + + fReceiveView->AppendOtherMessage(uname.String(), message.String()); + + // Message received, clear status anyway + fStatus->SetText(""); + + fMessageCount++; + + // Check if the user want the notification + if (!CayaPreferences::Item()->NotifyNewMessage) + break; + + BString notify_message; + notify_message << "You've got "; + notify_message << fMessageCount; + if (fMessageCount==1) { + notify_message << " new message from "; + } else { + notify_message << " new messages from "; + }; + notify_message << uname; + + BNotification notification(B_INFORMATION_NOTIFICATION); + notification.SetGroup(BString("Caya")); + notification.SetTitle(BString("New message")); + notification.SetIcon(sender->AvatarBitmap()); + notification.SetContent(notify_message); + notification.SetMessageID(uname); + notification.Send(); + + break; + } + case IM_LOGS_RECEIVED: + { + BStringList logs; + if (msg->FindStrings("log", &logs) != B_OK) + return; + + for (int i = logs.CountStrings(); i >= 0; i--) + fReceiveView->AppendGenericMessage(logs.StringAt(i).String()); + + break; + } + case IM_CONTACT_STARTED_TYPING: + fStatus->SetText("Contact is typing..."); + break; + case IM_CONTACT_STOPPED_TYPING: + fStatus->SetText(""); + break; + case IM_CONTACT_GONE: + fStatus->SetText("Contact closed the chat window!"); + snooze(10000); + fStatus->SetText(""); + break; + default: + break; + } +} + + +void +ConversationView::ObserveString(int32 what, BString str) +{ +// switch (what) { +// case STR_CONTACT_NAME: +// if (Lock()) { +// SetTitle(str); +// Unlock(); +// } +// break; +// case STR_PERSONAL_STATUS: +// break; +// } +} + + +void +ConversationView::ObservePointer(int32 what, void* ptr) +{ +// switch (what) { +// case PTR_AVATAR_BITMAP: +// break; +// } +} + + +void +ConversationView::ObserveInteger(int32 what, int32 val) +{ + switch (what) { + case INT_CONTACT_STATUS: + AppendStatus((CayaStatus)val); + break; + } +} + + +void +ConversationView::AppendStatus(CayaStatus status) +{ + BString message(fContact->GetName()); + + switch (status) { + case CAYA_ONLINE: + message << " is available"; + break; + case CAYA_AWAY: + message << " is away"; + break; + case CAYA_DO_NOT_DISTURB: + message << " is busy, please do not disturb!"; + break; + case CAYA_CUSTOM_STATUS: + message << " has set a custom status."; + break; + case CAYA_INVISIBLE: + message << " is invisible."; + break; + case CAYA_OFFLINE: + message << " is offline"; + break; + default: + break; + } + + fReceiveView->Append(message.String(), COL_TEXT, COL_TEXT, R_TEXT); + fReceiveView->Append("\n", COL_TEXT, COL_TEXT, R_TEXT); + fReceiveView->ScrollToSelection(); +} + + diff --git a/application/views/ConversationView.h b/application/views/ConversationView.h new file mode 100644 index 0000000..85a4fd7 --- /dev/null +++ b/application/views/ConversationView.h @@ -0,0 +1,59 @@ +/* + * Copyright 2009-2011, Andrea Anzani. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _CHAT_VIEW_H +#define _CHAT_VIEW_H + +#include +#include +#include +#include +#include +#include "Observer.h" + +#include "CayaConstants.h" + +class BitmapView; +class Conversation; +class CayaRenderView; +class Contact; + + +class ConversationView : public BGroupView { +public: + ConversationView(Conversation* chat); + +// virtual void ShowWindow(); + + virtual void MessageReceived(BMessage* message); +// void WindowActivated(bool active); + virtual bool QuitRequested(); + + Conversation* GetConversation(); + + void UpdateAvatar(); + void UpdatePersonalMessage(); + void ImMessage(BMessage* msg); + + void ObserveString(int32 what, BString str); + void ObservePointer(int32 what, void* ptr); + void ObserveInteger(int32 what, int32 val); + void AppendStatus(CayaStatus status); + + void AvoidFocus(bool avoid); +private: + Conversation* fConversation; + Contact* fContact; + CayaRenderView* fReceiveView; + BStringView* fStatus; + BTextView* fPersonalMessage; + BitmapView* fProtocolView; + BitmapView* fAvatar; + int32 fMessageCount; + +}; + + +#endif // _CHAT_VIEW_H +