From 4ec6c3a042bbc8e2e94b2ccd19c1e9289232d1e4 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Wed, 2 Nov 2011 14:57:43 +0000 Subject: [PATCH] Merge patch by plfiorini : Some changes to the API for notifications. * Don't go through be_roster to send a notification, but use Notification->Send() instead. * Rename App to Group to make the purpose clearer And some changes to the notification code itself: * Use the Notification class as the way to convey informations about a notification. Allows easier extension of this class * Code cleanup * Use of the layout kit for the notify window Unfortunately, the latter part clashes quite a bit with the changes I already did to the notification window, so it's now quite broken. Working on that next, but I wanted to separate that work from the patch ... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@43114 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/app/Notification.h | 21 +- headers/os/app/Roster.h | 5 - headers/os/mail/MailSettings.h | 9 - src/bin/notify.cpp | 86 ++--- src/kits/notification/AppUsage.cpp | 47 +-- src/kits/notification/Notifications.cpp | 2 - src/servers/mail/MailDaemon.cpp | 4 +- src/servers/mail/Notifier.cpp | 6 +- src/servers/notification/AppGroupView.cpp | 98 ++--- src/servers/notification/AppGroupView.h | 69 ++-- src/servers/notification/BorderView.cpp | 114 ------ src/servers/notification/BorderView.h | 31 -- src/servers/notification/Jamfile | 4 +- .../notification/NotificationServer.cpp | 23 +- src/servers/notification/NotificationServer.h | 2 +- src/servers/notification/NotificationView.cpp | 364 +++++------------- src/servers/notification/NotificationView.h | 47 +-- .../notification/NotificationWindow.cpp | 156 +++----- src/servers/notification/NotificationWindow.h | 18 +- 19 files changed, 321 insertions(+), 785 deletions(-) delete mode 100644 src/servers/notification/BorderView.cpp delete mode 100644 src/servers/notification/BorderView.h diff --git a/headers/os/app/Notification.h b/headers/os/app/Notification.h index 22d61ab522..d11e4b1c2c 100644 --- a/headers/os/app/Notification.h +++ b/headers/os/app/Notification.h @@ -6,6 +6,7 @@ #define _NOTIFICATION_H +#include #include #include #include @@ -22,15 +23,21 @@ enum notification_type { class BBitmap; -class BNotification { +class BNotification : public BArchivable { public: BNotification(notification_type type); - ~BNotification(); + BNotification(BMessage* archive); + virtual ~BNotification(); + + status_t InitCheck() const; + + static BArchivable* Instantiate(BMessage* archive); + virtual status_t Archive(BMessage* archive, bool deep = true) const; notification_type Type() const; - const char* Application() const; - void SetApplication(const BString& app); + const char* Group() const; + void SetGroup(const BString& group); const char* Title() const; void SetTitle(const BString& title); @@ -61,9 +68,13 @@ public: const BBitmap* Icon() const; status_t SetIcon(const BBitmap* icon); + status_t Send(bigtime_t timeout = -1); + private: + status_t fInitStatus; + notification_type fType; - BString fAppName; + BString fGroup; BString fTitle; BString fContent; BString fID; diff --git a/headers/os/app/Roster.h b/headers/os/app/Roster.h index e55e5189dc..50a6612b0e 100644 --- a/headers/os/app/Roster.h +++ b/headers/os/app/Roster.h @@ -13,7 +13,6 @@ class BFile; class BMimeType; class BNodeInfo; -class BNotification; struct app_info { @@ -117,10 +116,6 @@ class BRoster { void AddToRecentFolders(const entry_ref *folder, const char *appSig = 0) const; - // notifications - status_t Notify(const BNotification& notification, - bigtime_t timeout = -1) const; - // private/reserved stuff starts here class Private; diff --git a/headers/os/mail/MailSettings.h b/headers/os/mail/MailSettings.h index 1d04a03144..42ab039f66 100644 --- a/headers/os/mail/MailSettings.h +++ b/headers/os/mail/MailSettings.h @@ -28,15 +28,6 @@ typedef enum { } b_mail_status_window_option; -typedef enum { - B_MAIL_STATUS_LOOK_TITLED = 0, - B_MAIL_STATUS_LOOK_NORMAL_BORDER = 1, - B_MAIL_STATUS_LOOK_FLOATING = 2, - B_MAIL_STATUS_LOOK_THIN_BORDER = 3, - B_MAIL_STATUS_LOOK_NO_BORDER = 4 -} b_mail_status_window_look; - - class BMailSettings { public: BMailSettings(); diff --git a/src/bin/notify.cpp b/src/bin/notify.cpp index 7ad9170c10..c2030b6404 100644 --- a/src/bin/notify.cpp +++ b/src/bin/notify.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include @@ -19,7 +18,6 @@ #include #include #include -#include #include const char* kSignature = "application/x-vnd.Haiku-notify"; @@ -52,15 +50,15 @@ public: private: bool fHasGoodArguments; notification_type fType; - char* fAppName; - char* fTitle; - char* fMsgId; + BString fGroup; + BString fTitle; + BString fMsgId; float fProgress; bigtime_t fTimeout; - char* fIconFile; + BString fIconFile; entry_ref fFileRef; - char* fMessage; - char* fApp; + BString fContent; + BString fOnClickApp; bool fHasFile; entry_ref fFile; BList* fRefs; @@ -76,14 +74,8 @@ NotifyApp::NotifyApp() BApplication(kSignature), fHasGoodArguments(false), fType(B_INFORMATION_NOTIFICATION), - fAppName(NULL), - fTitle(NULL), - fMsgId(NULL), fProgress(0.0f), - fTimeout(0), - fIconFile(NULL), - fMessage(NULL), - fApp(NULL), + fTimeout(-1), fHasFile(false) { fRefs = new BList(); @@ -93,19 +85,12 @@ NotifyApp::NotifyApp() NotifyApp::~NotifyApp() { - free(fAppName); - free(fTitle); - free(fMsgId); - free(fIconFile); - free(fMessage); - free(fApp); - for (int32 i = 0; void* item = fRefs->ItemAt(i); i++) delete (BEntry*)item; delete fRefs; for (int32 i = 0; void* item = fArgv->ItemAt(i); i++) - free(item); + delete (BString*)item; delete fArgv; } @@ -134,25 +119,25 @@ NotifyApp::ArgvReceived(int32 argc, char** argv) if (strncmp(kTypeNames[i], argument, strlen(argument)) == 0) fType = (notification_type)i; } - } else if (strcmp(option, "app") == 0) - fAppName = strdup(argument); + } else if (strcmp(option, "group") == 0) + fGroup = argument; else if (strcmp(option, "title") == 0) - fTitle = strdup(argument); + fTitle = argument; else if (strcmp(option, "messageID") == 0) - fMsgId = strdup(argument); + fMsgId = argument; else if (strcmp(option, "progress") == 0) fProgress = atof(argument); else if (strcmp(option, "timeout") == 0) fTimeout = atol(argument) * 1000000; else if (strcmp(option, "icon") == 0) { - fIconFile = strdup(argument); + fIconFile = argument; - if (get_ref_for_path(fIconFile, &fFileRef) < B_OK) { + if (get_ref_for_path(fIconFile.String(), &fFileRef) < B_OK) { fprintf(stderr, "Bad icon path!\n\n"); return; } } else if (strcmp(option, "onClickApp") == 0) - fApp = strdup(argument); + fOnClickApp = argument; else if (strcmp(option, "onClickFile") == 0) { if (get_ref_for_path(argument, &fFile) != B_OK) { fprintf(stderr, "Bad path for --onClickFile!\n\n"); @@ -170,7 +155,7 @@ NotifyApp::ArgvReceived(int32 argc, char** argv) fRefs->AddItem(new BEntry(&ref)); } else if (strcmp(option, "onClickArgv") == 0) - fArgv->AddItem(strdup(argument)); + fArgv->AddItem(new BString(argument)); else { // Unrecognized option fprintf(stderr, "Unrecognized option --%s\n\n", option); @@ -188,17 +173,7 @@ NotifyApp::ArgvReceived(int32 argc, char** argv) } } - // Check for missing arguments - if (fAppName == NULL) { - fprintf(stderr, "Missing --app argument!\n\n"); - return; - } - if (fTitle == NULL) { - fprintf(stderr, "Missing --title argument!\n\n"); - return; - } - - fMessage = strdup(argv[index]); + fContent = argv[index]; fHasGoodArguments = true; } @@ -208,13 +183,13 @@ NotifyApp::_Usage() const fprintf(stderr, "Usage: notify [OPTION]... [MESSAGE]\n" "Send notifications to notification_server.\n" " --type \tNotification type,\n" - " \t : "); + " \t - \"information\" is assumed by default: "); for (int32 i = 0; kTypeNames[i]; i++) fprintf(stderr, kTypeNames[i + 1] ? "%s|" : "%s\n", kTypeNames[i]); fprintf(stderr, - " --app \tApplication name\n" + " --group \tGroup\n" " --title \tMessage title\n" " --messageID <msg id>\tMessage ID\n" " --progress <float>\tProgress, value between 0.0 and 1.0 - if type is set to progress\n" @@ -256,17 +231,20 @@ NotifyApp::ReadyToRun() { if (HasGoodArguments()) { BNotification notification(fType); - notification.SetApplication(fAppName); - notification.SetTitle(fTitle); - notification.SetContent(fMessage); + if (fGroup != "") + notification.SetGroup(fGroup); + if (fTitle != "") + notification.SetTitle(fTitle); + if (fContent != "") + notification.SetContent(fContent); - if (fMsgId != NULL) + if (fMsgId != "") notification.SetMessageID(fMsgId); if (fType == B_PROGRESS_NOTIFICATION) notification.SetProgress(fProgress); - if (fIconFile != NULL) { + if (fIconFile != "") { BBitmap* bitmap = _GetBitmap(&fFileRef); if (bitmap) { notification.SetIcon(bitmap); @@ -274,8 +252,8 @@ NotifyApp::ReadyToRun() } } - if (fApp != NULL) - notification.SetOnClickApp(fApp); + if (fOnClickApp != "") + notification.SetOnClickApp(fOnClickApp); if (fHasFile) notification.SetOnClickFile(&fFile); @@ -289,11 +267,11 @@ NotifyApp::ReadyToRun() } for (int32 i = 0; void* item = fArgv->ItemAt(i); i++) { - const char* arg = (const char*)item; - notification.AddOnClickArg(arg); + BString* arg = (BString*)item; + notification.AddOnClickArg(arg->String()); } - status_t ret = be_roster->Notify(notification, fTimeout); + status_t ret = notification.Send(fTimeout); if (ret != B_OK) { fprintf(stderr, "Failed to deliver notification: %s\n", strerror(ret)); diff --git a/src/kits/notification/AppUsage.cpp b/src/kits/notification/AppUsage.cpp index 7310796aaa..2e1cb72521 100644 --- a/src/kits/notification/AppUsage.cpp +++ b/src/kits/notification/AppUsage.cpp @@ -27,9 +27,8 @@ AppUsage::AppUsage() } -AppUsage::AppUsage(entry_ref ref, const char* name, bool allow) +AppUsage::AppUsage(const char* name, bool allow) : - fRef(ref), fName(name), fAllow(allow) { @@ -38,7 +37,7 @@ AppUsage::AppUsage(entry_ref ref, const char* name, bool allow) AppUsage::~AppUsage() { - notify_t::iterator nIt; + notification_t::iterator nIt; for (nIt = fNotifications.begin(); nIt != fNotifications.end(); nIt++) delete nIt->second; } @@ -55,13 +54,12 @@ status_t AppUsage::Flatten(void* buffer, ssize_t numBytes) const { BMessage msg; - msg.AddString("app_name", fName); - msg.AddRef("app_ref", &fRef); - msg.AddBool("app_allow", fAllow); + msg.AddString("signature", fName); + msg.AddBool("allow", fAllow); - notify_t::const_iterator nIt; + notification_t::const_iterator nIt; for (nIt = fNotifications.begin(); nIt != fNotifications.end(); nIt++) - msg.AddFlat("notify", nIt->second); + msg.AddFlat("notification", nIt->second); if (numBytes < msg.FlattenedSize()) return B_ERROR; @@ -74,13 +72,12 @@ ssize_t AppUsage::FlattenedSize() const { BMessage msg; - msg.AddString("app_name", fName); - msg.AddRef("app_ref", &fRef); - msg.AddBool("app_allow", fAllow); + msg.AddString("signature", fName); + msg.AddBool("allow", fAllow); - notify_t::const_iterator nIt; + notification_t::const_iterator nIt; for (nIt = fNotifications.begin(); nIt != fNotifications.end(); nIt++) - msg.AddFlat("notify", nIt->second); + msg.AddFlat("notification", nIt->second); return msg.FlattenedSize(); } @@ -113,21 +110,20 @@ AppUsage::Unflatten(type_code code, const void* buffer, status = msg.Unflatten((const char*)buffer); if (status == B_OK) { - msg.FindString("app_name", &fName); - msg.FindRef("app_ref", &fRef); - msg.FindBool("app_allow", &fAllow); + msg.FindString("signature", &fName); + msg.FindBool("allow", &fAllow); type_code type; int32 count = 0; - status = msg.GetInfo("notify", &type, &count); + status = msg.GetInfo("notification", &type, &count); if (status != B_OK) return status; for (int32 i = 0; i < count; i++) { - NotificationReceived *notify = new NotificationReceived(); - msg.FindFlat("notify", i, notify); - fNotifications[notify->Title()] = notify; + NotificationReceived *notification = new NotificationReceived(); + msg.FindFlat("notification", i, notification); + fNotifications[notification->Title()] = notification; } status = B_OK; @@ -137,13 +133,6 @@ AppUsage::Unflatten(type_code code, const void* buffer, } -entry_ref -AppUsage::Ref() -{ - return fRef; -} - - const char* AppUsage::Name() { @@ -157,7 +146,7 @@ AppUsage::Allowed(const char* title, notification_type type) bool allowed = fAllow; if (allowed) { - notify_t::iterator nIt = fNotifications.find(title); + notification_t::iterator nIt = fNotifications.find(title); if (nIt == fNotifications.end()) { allowed = true; fNotifications[title] = new NotificationReceived(title, type); @@ -182,7 +171,7 @@ AppUsage::Allowed() NotificationReceived* AppUsage::NotificationAt(int32 index) { - notify_t::iterator nIt = fNotifications.begin(); + notification_t::iterator nIt = fNotifications.begin(); for (int32 i = 0; i < index; i++) nIt++; diff --git a/src/kits/notification/Notifications.cpp b/src/kits/notification/Notifications.cpp index e386d74dd7..cefdc6afd2 100644 --- a/src/kits/notification/Notifications.cpp +++ b/src/kits/notification/Notifications.cpp @@ -20,5 +20,3 @@ const char* kTimeoutName = "timeout"; // Display settings const char* kWidthName = "width"; const char* kIconSizeName = "icon size"; -const char* kLayoutName = "layout"; - diff --git a/src/servers/mail/MailDaemon.cpp b/src/servers/mail/MailDaemon.cpp index ebc03c81fb..54597692c8 100644 --- a/src/servers/mail/MailDaemon.cpp +++ b/src/servers/mail/MailDaemon.cpp @@ -191,7 +191,7 @@ MailDaemonApp::ReadyToRun() fCentralBeep = false; fNotification = new BNotification(B_INFORMATION_NOTIFICATION); - fNotification->SetApplication(B_TRANSLATE("Mail status")); + fNotification->SetGroup(B_TRANSLATE("Mail status")); fNotification->SetTitle(string); fNotification->SetMessageID("daemon_status"); @@ -390,7 +390,7 @@ MailDaemonApp::MessageReceived(BMessage* msg) fNotification->SetTitle(string.String()); if (fNotifyMode != B_MAIL_SHOW_STATUS_WINDOW_NEVER) - be_roster->Notify(*fNotification); + fNotification->Send(); break; } diff --git a/src/servers/mail/Notifier.cpp b/src/servers/mail/Notifier.cpp index c0c0b37066..b6ce8dd30c 100644 --- a/src/servers/mail/Notifier.cpp +++ b/src/servers/mail/Notifier.cpp @@ -42,7 +42,7 @@ DefaultNotifier::DefaultNotifier(const char* accountName, bool inbound, // Two windows for each acocunt : one for sending and the other for // receiving mails fNotification.SetMessageID(identifier); - fNotification.SetApplication(B_TRANSLATE("Mail Status")); + fNotification.SetGroup(B_TRANSLATE("Mail Status")); fNotification.SetTitle(desc); app_info info; @@ -127,7 +127,7 @@ DefaultNotifier::ReportProgress(int bytes, int messages, const char* message) if ((!fIsInbound && fShowMode | B_MAIL_SHOW_STATUS_WINDOW_WHEN_SENDING) || (fIsInbound && fShowMode | B_MAIL_SHOW_STATUS_WINDOW_WHEN_ACTIVE)) - be_roster->Notify(fNotification, timeout); + fNotification.Send(timeout); } @@ -137,5 +137,5 @@ DefaultNotifier::ResetProgress(const char* message) fNotification.SetProgress(0); if (message != NULL) fNotification.SetTitle(message); - be_roster->Notify(fNotification, 0); + fNotification.Send(0); } diff --git a/src/servers/notification/AppGroupView.cpp b/src/servers/notification/AppGroupView.cpp index 2e8b8c5b91..5d931bf9db 100644 --- a/src/servers/notification/AppGroupView.cpp +++ b/src/servers/notification/AppGroupView.cpp @@ -13,6 +13,9 @@ #include <algorithm> +#include <GroupLayout.h> +#include <GroupView.h> + #include "AppGroupView.h" #include "NotificationWindow.h" @@ -21,13 +24,16 @@ AppGroupView::AppGroupView(NotificationWindow* win, const char* label) : - BView(BRect(0, 0, win->ViewWidth(), 1), label, B_FOLLOW_LEFT_RIGHT, - B_WILL_DRAW|B_FULL_UPDATE_ON_RESIZE|B_FRAME_EVENTS), + BBox(B_FANCY_BORDER, (fView = new BGroupView(B_VERTICAL, 10))), fLabel(label), fParent(win), fCollapsed(false) { - Show(); + // If no group was specified we don't have any border or label + if (label == NULL) + SetBorder(B_NO_BORDER); + else + SetLabel(label); } @@ -36,6 +42,7 @@ AppGroupView::~AppGroupView() } +/* void AppGroupView::AttachedToWindow() { @@ -43,8 +50,9 @@ AppGroupView::AttachedToWindow() SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetHighColor(ui_color(B_PANEL_TEXT_COLOR)); } +*/ - +/* void AppGroupView::Draw(BRect updateRect) { @@ -120,7 +128,7 @@ AppGroupView::Draw(BRect updateRect) Sync(); } - +*/ void AppGroupView::MouseDown(BPoint point) @@ -131,7 +139,7 @@ AppGroupView::MouseDown(BPoint point) int32 children = fInfo.size(); for (int32 i = 0; i < children; i++) { - fInfo[i]->RemoveSelf(); + fView->GetLayout()->RemoveView(fInfo[i]); delete fInfo[i]; } fInfo.clear(); @@ -143,41 +151,11 @@ AppGroupView::MouseDown(BPoint point) } if (changed) { - ResizeViews(); - Invalidate(); + _ResizeViews(); } } -void -AppGroupView::GetPreferredSize(float* width, float* height) -{ - font_height fh; - be_bold_font->GetHeight(&fh); - - float h = fh.ascent + fh.leading + fh.leading; - h += kEdgePadding * 2; // Padding between top and bottom of label - - if (!fCollapsed) { - int32 children = fInfo.size(); - - for (int32 i = 0; i < children; i++) { - float childHeight = 0; - float childWidth = 0; - - fInfo[i]->GetPreferredSize(&childWidth, &childHeight); - - h += childHeight; - } - } - - h += kEdgePadding; - - *width = fParent->ViewWidth(); - *height = h; -} - - void AppGroupView::MessageReceived(BMessage* msg) { @@ -192,16 +170,14 @@ AppGroupView::MessageReceived(BMessage* msg) if (vIt != fInfo.end()) { fInfo.erase(vIt); - view->RemoveSelf(); + fView->GetLayout()->RemoveView(view); delete view; } - ResizeViews(); - Invalidate(); + if (Window() != NULL) + Window()->PostMessage(msg); - // When all the views are destroy, save app filters - if (fInfo.size() == 0) - dynamic_cast<NotificationWindow*>(Window())->SaveAppFilters(); + _ResizeViews(); break; } default: @@ -214,13 +190,14 @@ void AppGroupView::AddInfo(NotificationView* view) { BString id = view->MessageID(); + bool found = false; + if (id.Length() > 0) { int32 children = fInfo.size(); - bool found = false; for (int32 i = 0; i < children; i++) { - if (fInfo[i]->HasMessageID(id.String())) { - fInfo[i]->RemoveSelf(); + if (id == fInfo[i]->MessageID()) { + fView->GetLayout()->RemoveView(fInfo[i]); delete fInfo[i]; fInfo[i] = view; @@ -229,28 +206,23 @@ AppGroupView::AddInfo(NotificationView* view) break; } } + } - if (!found) - fInfo.push_back(view); - } else + if (!found) fInfo.push_back(view); + fView->GetLayout()->AddView(view); - if (fParent->IsHidden()) - fParent->Show(); if (IsHidden()) Show(); if (view->IsHidden()) view->Show(); - AddChild(view); - - ResizeViews(); - Invalidate(); + _ResizeViews(); } void -AppGroupView::ResizeViews() +AppGroupView::_ResizeViews() { font_height fh; be_bold_font->GetHeight(&fh); @@ -268,22 +240,14 @@ AppGroupView::ResizeViews() offset += fInfo[i]->Bounds().Height(); if (fInfo[i]->IsHidden()) fInfo[i]->Show(); - fInfo[i]->SetPosition(false, false); - }; + } } else { for (int32 i = 0; i < children; i++) if (!fInfo[i]->IsHidden()) fInfo[i]->Hide(); } - if (children == 1) - fInfo[0]->SetPosition(true, true); - else if (children > 1) { - fInfo[0]->SetPosition(true, false); - fInfo[children - 1]->SetPosition(false, true); - } - - ResizeTo(fParent->ViewWidth(), offset); + ResizeTo(fParent->Width(), offset); float labelOffset = fh.ascent + fh.leading; BRect borderRect = Bounds().InsetByCopy(kEdgePadding, kEdgePadding); @@ -299,8 +263,6 @@ AppGroupView::ResizeViews() fCloseRect.top += kEdgePadding * 1.5; fCloseRect.left = fCloseRect.right - kCloseSize; fCloseRect.bottom = fCloseRect.top + kCloseSize; - - fParent->ResizeAll(); } diff --git a/src/servers/notification/AppGroupView.h b/src/servers/notification/AppGroupView.h index eeb9a81047..d0ec4787f9 100644 --- a/src/servers/notification/AppGroupView.h +++ b/src/servers/notification/AppGroupView.h @@ -1,50 +1,47 @@ /* - * Copyright 2005-2008, Mikael Eiman. - * Copyright 2005-2008, Michael Davidson. + * Copyright 2010, Haiku, Inc. All Rights Reserved. + * Copyright 2008-2009, Pier Luigi Fiorini. All Rights Reserved. + * Copyright 2004-2008, Michael Davidson. All Rights Reserved. + * Copyright 2004-2007, Mikael Eiman. All Rights Reserved. * Distributed under the terms of the MIT License. - * - * Authors: - * Mikael Eiman <mikael@eiman.tv> - * Michael Davidson <slaad@bong.com.au> */ - -#ifndef APPGROUPVIEW_H -#define APPGROUPVIEW_H +#ifndef _APP_GROUP_VIEW_H +#define _APP_GROUP_VIEW_H #include <vector> +#include <Box.h> #include <String.h> -#include <View.h> + +class BGroupView; class NotificationWindow; class NotificationView; -typedef std::vector<NotificationView *> infoview_t; +typedef std::vector<NotificationView*> infoview_t; -class AppGroupView : public BView { - public: - AppGroupView(NotificationWindow *win, const char *label); - ~AppGroupView(void); - - // Hooks - void AttachedToWindow(void); - void Draw(BRect bounds); - void MouseDown(BPoint point); - void GetPreferredSize(float *width, float *height); - void MessageReceived(BMessage *msg); - - // Public - void AddInfo(NotificationView *view); - void ResizeViews(void); - bool HasChildren(void); - - private: - BString fLabel; - NotificationWindow *fParent; - infoview_t fInfo; - bool fCollapsed; - BRect fCloseRect; - BRect fCollapseRect; +class AppGroupView : public BBox { +public: + AppGroupView(NotificationWindow* win, const char* label); + ~AppGroupView(); + + virtual void MouseDown(BPoint point); + virtual void MessageReceived(BMessage* msg); + + bool HasChildren(); + + void AddInfo(NotificationView* view); + +private: + void _ResizeViews(); + + BString fLabel; + NotificationWindow* fParent; + BGroupView* fView; + infoview_t fInfo; + bool fCollapsed; + BRect fCloseRect; + BRect fCollapseRect; }; -#endif +#endif // _APP_GROUP_VIEW_H diff --git a/src/servers/notification/BorderView.cpp b/src/servers/notification/BorderView.cpp deleted file mode 100644 index 659ec195de..0000000000 --- a/src/servers/notification/BorderView.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2010, Haiku, Inc. All Rights Reserved. - * Copyright 2008-2009, Pier Luigi Fiorini. All Rights Reserved. - * Copyright 2004-2008, Michael Davidson. All Rights Reserved. - * Copyright 2004-2007, Mikael Eiman. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Michael Davidson, slaad@bong.com.au - * Mikael Eiman, mikael@eiman.tv - * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com - */ - -#include "BorderView.h" - -const float kBorderWidth = 2.0f; -const int32 kTitleSize = 14; - - -BorderView::BorderView(BRect rect, const char* text) - : - BView(rect, "NotificationBorderView", B_FOLLOW_ALL, - B_WILL_DRAW | B_FRAME_EVENTS), - fTitle(text) -{ - SetViewColor(B_TRANSPARENT_COLOR); -} - - -BorderView::~BorderView() -{ -} - - -void -BorderView::FrameResized(float, float) -{ - Invalidate(); -} - - -void -BorderView::Draw(BRect rect) -{ - rgb_color col_bg = ui_color(B_PANEL_BACKGROUND_COLOR); - rgb_color col_text = tint_color(col_bg, B_LIGHTEN_MAX_TINT); - rgb_color col_text_shadow = tint_color(col_bg, B_DARKEN_MAX_TINT); - - // Background - SetDrawingMode(B_OP_COPY); - SetHighColor(col_bg); - FillRect(rect); - - // Text - SetLowColor(col_bg); - SetDrawingMode(B_OP_ALPHA); - SetFont(be_bold_font); - SetFontSize(kTitleSize); - - BFont font; - GetFont(&font); - - font_height fh; - font.GetHeight(&fh); - - // float line_height = fh.ascent + fh.descent + fh.leading; - - float text_pos = fh.ascent; - - SetHighColor(col_text); - DrawString(fTitle.String(), BPoint(kBorderWidth, text_pos)); - - SetHighColor(col_text_shadow); - DrawString(fTitle.String(), BPoint(kBorderWidth + 1, text_pos + 1)); - - // Content border - SetHighColor(tint_color(col_bg, B_DARKEN_2_TINT)); - - BRect content = Bounds(); -// content.InsetBy(kBorderWidth, kBorderWidth); - content.top += text_pos + fh.descent + 2; - - BRect content_line(content); -// content_line.InsetBy(-1, -1); - - StrokeRect(content_line); -} - - -void -BorderView::GetPreferredSize(float* w, float* h) -{ - SetFont(be_bold_font); - SetFontSize(kTitleSize); - - BFont font; - GetFont(&font); - - font_height fh; - font.GetHeight(&fh); - - float line_height = fh.ascent + fh.descent; - - *w = 2 * kBorderWidth + StringWidth(fTitle.String()); - *h = 2 * kBorderWidth + line_height + 3; - *w = *h = 0; -} - - -float -BorderView::BorderSize() -{ - return 0; -} diff --git a/src/servers/notification/BorderView.h b/src/servers/notification/BorderView.h deleted file mode 100644 index 2e1bea9cc2..0000000000 --- a/src/servers/notification/BorderView.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2010, Haiku, Inc. All Rights Reserved. - * Copyright 2008-2009, Pier Luigi Fiorini. All Rights Reserved. - * Copyright 2004-2008, Michael Davidson. All Rights Reserved. - * Copyright 2004-2007, Mikael Eiman. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _BORDER_VIEW_H -#define _BORDER_VIEW_H - -#include <View.h> -#include <String.h> - -class BorderView : public BView { -public: - BorderView(BRect, const char*); - virtual ~BorderView(); - - virtual void Draw(BRect updateRect); - - virtual void GetPreferredSize(float*, float*); - - virtual void FrameResized(float, float); - - float BorderSize(); - -private: - BString fTitle; -}; - -#endif // _BORDER_VIEW_H diff --git a/src/servers/notification/Jamfile b/src/servers/notification/Jamfile index fa091bc405..054b20a4e6 100644 --- a/src/servers/notification/Jamfile +++ b/src/servers/notification/Jamfile @@ -4,11 +4,10 @@ UsePrivateHeaders notification ; Server notification_server : AppGroupView.cpp - BorderView.cpp NotificationServer.cpp NotificationView.cpp NotificationWindow.cpp - : be $(TARGET_LIBSTDC++) libicon.a libnotification.a $(HAIKU_LOCALE_LIBS) + : be translation $(TARGET_LIBSTDC++) libnotification.a $(HAIKU_LOCALE_LIBS) : notification_server.rdef ; @@ -20,5 +19,4 @@ DoCatalogs notification_server : NotificationWindow.cpp ; -Depends notification_server : libicon.a ; Depends notification_server : libnotification.a ; diff --git a/src/servers/notification/NotificationServer.cpp b/src/servers/notification/NotificationServer.cpp index bd874e380e..0b528c24af 100644 --- a/src/servers/notification/NotificationServer.cpp +++ b/src/servers/notification/NotificationServer.cpp @@ -24,7 +24,6 @@ const char* kSoundNames[] = { NotificationServer::NotificationServer() : BApplication(kNotificationServerSignature) { - fWindow = new NotificationWindow(); } @@ -33,6 +32,13 @@ NotificationServer::~NotificationServer() } +void +NotificationServer::ReadyToRun() +{ + fWindow = new NotificationWindow(); +} + + void NotificationServer::MessageReceived(BMessage* message) { @@ -61,17 +67,6 @@ NotificationServer::MessageReceived(BMessage* message) } -bool -NotificationServer::QuitRequested() -{ - if (fWindow && fWindow->Lock()) { - fWindow->Quit(); - fWindow = NULL; - } - return true; -} - - status_t NotificationServer::GetSupportedSuites(BMessage* msg) { @@ -110,8 +105,8 @@ main(int argc, char* argv[]) add_system_beep_event(kSoundNames[i++], 0); // Start! - NotificationServer* server = new NotificationServer(); - server->Run(); + NotificationServer server; + server.Run(); return 0; } diff --git a/src/servers/notification/NotificationServer.h b/src/servers/notification/NotificationServer.h index aff0da122f..7a504fbf33 100644 --- a/src/servers/notification/NotificationServer.h +++ b/src/servers/notification/NotificationServer.h @@ -14,8 +14,8 @@ public: NotificationServer(); virtual ~NotificationServer(); + virtual void ReadyToRun(); virtual void MessageReceived(BMessage* message); - virtual bool QuitRequested(); virtual status_t GetSupportedSuites(BMessage* msg); virtual BHandler* ResolveSpecifier(BMessage* msg, int32 index, BMessage* spec, diff --git a/src/servers/notification/NotificationView.cpp b/src/servers/notification/NotificationView.cpp index 8241542496..21307cad14 100644 --- a/src/servers/notification/NotificationView.cpp +++ b/src/servers/notification/NotificationView.cpp @@ -13,28 +13,16 @@ * Adrien Destugues <pulkomandy@pulkomandy.ath.cx> */ -#include <stdlib.h> - #include <ControlLook.h> -#include <Font.h> -#include <IconUtils.h> +#include <LayoutUtils.h> #include <Messenger.h> -#include <Picture.h> -#include <PropertyInfo.h> -#include <Region.h> -#include <Resources.h> +#include <Path.h> #include <Roster.h> #include <StatusBar.h> -#include <StringView.h> -#include <TranslationUtils.h> #include "NotificationView.h" #include "NotificationWindow.h" -const char* kSmallIconAttribute = "BEOS:M:STD_ICON"; -const char* kLargeIconAttribute = "BEOS:L:STD_ICON"; -const char* kIconAttribute = "BEOS:ICON"; - static const int kIconStripeWidth = 32; property_info message_prop_list[] = { @@ -55,46 +43,25 @@ property_info message_prop_list[] = { NotificationView::NotificationView(NotificationWindow* win, - notification_type type, const char* app, const char* title, const char* text, - BMessage* details) + BNotification* notification, bigtime_t timeout) : - BView(BRect(0, 0, win->ViewWidth(), 1), "NotificationView", - B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE + BView("NotificationView", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS), fParent(win), - fType(type), + fNotification(notification), + fTimeout(timeout), fRunner(NULL), - fProgress(0.0f), - fMessageID(""), - fDetails(details), - fBitmap(NULL), - fIsFirst(false), - fIsLast(false) + fBitmap(NULL) { - BMessage iconMsg; - if (fDetails->FindMessage("icon", &iconMsg) == B_OK) - fBitmap = new BBitmap(&iconMsg); + if (fNotification->Icon() != NULL) + fBitmap = new BBitmap(fNotification->Icon()); - if (!fBitmap) - _LoadIcon(); + if (fTimeout <= 0) + fTimeout = fParent->Timeout() * 1000000; - const char* messageID = NULL; - if (fDetails->FindString("messageID", &messageID) == B_OK) - fMessageID = messageID; + SetText(); - if (fDetails->FindFloat("progress", &fProgress) != B_OK) - fProgress = 0.0f; - - // Progress is between 0 and 1 - if (fProgress < 0.0f) - fProgress = 0.0f; - if (fProgress > 1.0f) - fProgress = 1.0f; - - SetText(app, title, text); - ResizeToPreferred(); - - switch (type) { + switch (fNotification->Type()) { case B_IMPORTANT_NOTIFICATION: SetViewColor(255, 255, 255); SetLowColor(255, 255, 255); @@ -110,18 +77,18 @@ NotificationView::NotificationView(NotificationWindow* win, BStatusBar* progress = new BStatusBar(frame, "progress"); progress->SetBarHeight(12.0f); progress->SetMaxValue(1.0f); - progress->Update(fProgress); + progress->Update(fNotification->Progress()); BString label = ""; - label << (int)(fProgress * 100) << " %"; + label << (int)(fNotification->Progress() * 100) << " %"; progress->SetTrailingText(label); AddChild(progress); } + // fall through default: SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - break; } } @@ -129,8 +96,8 @@ NotificationView::NotificationView(NotificationWindow* win, NotificationView::~NotificationView() { delete fRunner; - delete fDetails; delete fBitmap; + delete fNotification; LineInfoList::iterator lIt; for (lIt = fLines.begin(); lIt != fLines.end(); lIt++) @@ -143,13 +110,8 @@ NotificationView::AttachedToWindow() { BMessage msg(kRemoveView); msg.AddPointer("view", this); - bigtime_t timeout = -1; - if (fDetails->FindInt64("timeout", &timeout) != B_OK) - timeout = fParent->Timeout() * 1000000; - - if (timeout > 0) - fRunner = new BMessageRunner(BMessenger(Parent()), &msg, timeout, 1); + fRunner = new BMessageRunner(BMessenger(Parent()), &msg, fTimeout, 1); } @@ -171,19 +133,19 @@ NotificationView::MessageReceived(BMessage* msg) if (msgOkay) { if (strcmp(property, "type") == 0) - reply.AddInt32("result", fType); + reply.AddInt32("result", fNotification->Type()); - if (strcmp(property, "app") == 0) - reply.AddString("result", fApp); + if (strcmp(property, "group") == 0) + reply.AddString("result", fNotification->Group()); if (strcmp(property, "title") == 0) - reply.AddString("result", fTitle); + reply.AddString("result", fNotification->Title()); if (strcmp(property, "content") == 0) - reply.AddString("result", fText); + reply.AddString("result", fNotification->Content()); if (strcmp(property, "progress") == 0) - reply.AddFloat("result", fProgress); + reply.AddFloat("result", fNotification->Progress()); if ((strcmp(property, "icon") == 0) && fBitmap) { BMessage archive; @@ -213,14 +175,19 @@ NotificationView::MessageReceived(BMessage* msg) msgOkay = false; if (msgOkay) { - if (strcmp(property, "app") == 0) - msg->FindString("data", &fApp); + const char* value = NULL; + + if (strcmp(property, "group") == 0) + if (msg->FindString("data", &value) == B_OK) + fNotification->SetGroup(value); if (strcmp(property, "title") == 0) - msg->FindString("data", &fTitle); + if (msg->FindString("data", &value) == B_OK) + fNotification->SetTitle(value); if (strcmp(property, "content") == 0) - msg->FindString("data", &fText); + if (msg->FindString("data", &value) == B_OK) + fNotification->SetContent(value); if (strcmp(property, "icon") == 0) { BMessage archive; @@ -230,7 +197,7 @@ NotificationView::MessageReceived(BMessage* msg) } } - SetText(Application(), Title(), Text()); + SetText(); Invalidate(); reply.AddInt32("error", B_OK); @@ -242,33 +209,12 @@ NotificationView::MessageReceived(BMessage* msg) msg->SendReply(&reply); break; } - case kRemoveView: - { - BMessage remove(kRemoveView); - remove.AddPointer("view", this); - BMessenger msgr(Window()); - msgr.SendMessage( &remove ); - break; - } default: BView::MessageReceived(msg); } } -void -NotificationView::GetPreferredSize(float* w, float* h) -{ - *w = fParent->ViewWidth(); - *h = fHeight; - - if (fType == B_PROGRESS_NOTIFICATION) { - *h += 16 + kEdgePadding; - // 16 is progress bar default size as stated in the BeBook - } -} - - void NotificationView::Draw(BRect updateRect) { @@ -295,7 +241,7 @@ NotificationView::Draw(BRect updateRect) float iy = (Bounds().Height() - iconSize) / 4.0; // Icon is vertically centered in view - if (fType == B_PROGRESS_NOTIFICATION) + if (fNotification->Type() == B_PROGRESS_NOTIFICATION) { // Move icon up by half progress bar height if it's present iy -= (progRect.Height() + kEdgePadding); @@ -363,46 +309,44 @@ NotificationView::MouseDown(BPoint point) BList messages; entry_ref ref; - if (fDetails->FindString("onClickApp", &launchString) == B_OK) - if (be_roster->FindApp(launchString.String(), &appRef) == B_OK) - useArgv = true; - if (fDetails->FindRef("onClickFile", &launchRef) == B_OK) { - if (be_roster->FindApp(&launchRef, &appRef) == B_OK) - useArgv = true; + if (fNotification->OnClickApp() != NULL + && be_roster->FindApp(fNotification->OnClickApp(), &appRef) + == B_OK) { + useArgv = true; } - if (fDetails->FindRef("onClickRef", &ref) == B_OK) { - for (int32 i = 0; fDetails->FindRef("onClickRef", i, &ref) == B_OK; i++) - refMsg.AddRef("refs", &ref); - - messages.AddItem((void*)&refMsg); + if (fNotification->OnClickFile() != NULL + && be_roster->FindApp( + (entry_ref*)fNotification->OnClickFile(), &appRef) + == B_OK) { + useArgv = true; } + for (int32 i = 0; i < fNotification->CountOnClickRefs(); i++) + refMsg.AddRef("refs", fNotification->OnClickRefAt(i)); + messages.AddItem((void*)&refMsg); + if (useArgv) { - type_code type; - int32 argc = 0; + int32 argc = fNotification->CountOnClickArgs() + 1; BString arg; BPath p(&appRef); argMsg.AddString("argv", p.Path()); - fDetails->GetInfo("onClickArgv", &type, &argc); - argMsg.AddInt32("argc", argc + 1); + argMsg.AddInt32("argc", argc); - for (int32 i = 0; fDetails->FindString("onClickArgv", i, &arg) == B_OK; i++) - argMsg.AddString("argv", arg); + for (int32 i = 0; i < argc - 1; i++) { + argMsg.AddString("argv", + fNotification->OnClickArgAt(i)); + } messages.AddItem((void*)&argMsg); } - BMessage tmp; - for (int32 i = 0; fDetails->FindMessage("onClickMsg", i, &tmp) == B_OK; i++) - messages.AddItem((void*)&tmp); - - if (fDetails->FindString("onClickApp", &launchString) == B_OK) - be_roster->Launch(launchString.String(), &messages); + if (fNotification->OnClickApp() != NULL) + be_roster->Launch(fNotification->OnClickApp(), &messages); else - be_roster->Launch(&launchRef, &messages); + be_roster->Launch(fNotification->OnClickFile(), &messages); } // Remove the info view after a click @@ -417,15 +361,31 @@ NotificationView::MouseDown(BPoint point) } -void -NotificationView::FrameResized( float w, float /*h*/) +BSize +NotificationView::MinSize() { - SetText(Application(), Title(), Text()); + return BLayoutUtils::ComposeSize(ExplicitMinSize(), _CalculateSize()); +} + + +BSize +NotificationView::MaxSize() +{ + return BLayoutUtils::ComposeSize(ExplicitMaxSize(), _CalculateSize()); +} + + +BSize +NotificationView::PreferredSize() +{ + return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), + _CalculateSize()); } BHandler* -NotificationView::ResolveSpecifier(BMessage* msg, int32 index, BMessage* spec, int32 form, const char* prop) +NotificationView::ResolveSpecifier(BMessage* msg, int32 index, BMessage* spec, + int32 form, const char* prop) { BPropertyInfo prop_info(message_prop_list); if (prop_info.FindMatch(msg, index, spec, form, prop) >= 0) { @@ -447,30 +407,8 @@ NotificationView::GetSupportedSuites(BMessage* msg) } -const char* -NotificationView::Application() const -{ - return fApp.Length() > 0 ? fApp.String() : NULL; -} - - -const char* -NotificationView::Title() const -{ - return fTitle.Length() > 0 ? fTitle.String() : NULL; -} - - -const char* -NotificationView::Text() const -{ - return fText.Length() > 0 ? fText.String() : NULL; -} - - void -NotificationView::SetText(const char* app, const char* title, const char* text, - float newMaxWidth) +NotificationView::SetText(float newMaxWidth) { if (newMaxWidth < 0) newMaxWidth = Bounds().Width() - (kEdgePadding * 2); @@ -481,10 +419,6 @@ NotificationView::SetText(const char* app, const char* title, const char* text, delete (*lIt); fLines.clear(); - fApp = app; - fTitle = title; - fText = text; - float iconRight = kIconStripeWidth; if (fBitmap != NULL) iconRight += fParent->IconSize(); @@ -499,7 +433,7 @@ NotificationView::SetText(const char* app, const char* title, const char* text, // Title LineInfo* titleLine = new LineInfo; - titleLine->text = fTitle; + titleLine->text = fNotification->Title(); titleLine->font = *be_bold_font; titleLine->location = BPoint(iconRight, y); @@ -514,7 +448,7 @@ NotificationView::SetText(const char* app, const char* title, const char* text, // Split text into chunks between certain characters and compose the lines. const char kSeparatorCharacters[] = " \n-\\/"; - BString textBuffer = fText; + BString textBuffer = fNotification->Content(); textBuffer.ReplaceAll("\t", " "); const char* chunkStart = textBuffer.String(); float maxWidth = newMaxWidth - kEdgePadding - iconRight; @@ -523,8 +457,7 @@ NotificationView::SetText(const char* app, const char* title, const char* text, while (chunkStart - textBuffer.String() < length) { size_t chunkLength = strcspn(chunkStart, kSeparatorCharacters) + 1; - // Start a new line if either we didn't start one before, - // the current offset + // Start a new line if we didn't start one before BString tempText; if (line != NULL) tempText.SetTo(line->text); @@ -539,20 +472,21 @@ NotificationView::SetText(const char* app, const char* title, const char* text, fLines.push_front(line); y += fontHeight; - // Skip the eventual new-line character at the beginning of this - // chunk. + // Skip the eventual new-line character at the beginning of this chunk if (chunkStart[0] == '\n') { chunkStart++; chunkLength--; } - // Skip more new-line characters and move the line further down. + + // Skip more new-line characters and move the line further down while (chunkStart[0] == '\n') { chunkStart++; chunkLength--; line->location.y += fontHeight; y += fontHeight; } - // Strip space at beginning of a new line. + + // Strip space at beginning of a new line while (chunkStart[0] == ' ') { chunkLength--; chunkStart++; @@ -563,7 +497,7 @@ NotificationView::SetText(const char* app, const char* title, const char* text, break; // Append the chunk to the current line, which was either a new - // line or the one from the previous iteration. + // line or the one from the previous iteration line->text.Append(chunkStart, chunkLength); chunkStart += chunkLength; @@ -573,130 +507,36 @@ NotificationView::SetText(const char* app, const char* title, const char* text, // Make sure icon fits if (fBitmap != NULL) { - float minHeight = 0; - if (fParent->Layout() == TitleAboveIcon) { - LineInfo* appLine = fLines.back(); - font_height fh; - appLine->font.GetHeight(&fh); - minHeight = appLine->location.y + fh.descent; - } + float minHeight = fBitmap->Bounds().Height() + 2 * kEdgePadding; - minHeight += fBitmap->Bounds().Height() + 2 * kEdgePadding; if (fHeight < minHeight) fHeight = minHeight; } - - BMessenger messenger(Parent()); - messenger.SendMessage(kResizeToFit); -} - - -bool -NotificationView::HasMessageID(const char* id) -{ - return fMessageID == id; } const char* -NotificationView::MessageID() +NotificationView::MessageID() const { - return fMessageID.String(); + return fNotification->MessageID(); } -void -NotificationView::SetPosition(bool first, bool last) +BSize +NotificationView::_CalculateSize() { - fIsFirst = first; - fIsLast = last; -} + BSize size; + // Parent width, minus the edge padding, minus the pensize + size.width = fParent->Width() - (kEdgePadding * 2) - (kPenSize * 2); + size.height = fHeight; -BBitmap* -NotificationView::_ReadNodeIcon(const char* fileName, icon_size size) -{ - BEntry entry(fileName, true); - - entry_ref ref; - entry.GetRef(&ref); - - BNode node(BPath(&ref).Path()); - - BBitmap* ret = new BBitmap(BRect(0, 0, (float)size - 1, (float)size - 1), B_RGBA32); - if (BIconUtils::GetIcon(&node, kIconAttribute, kSmallIconAttribute, - kLargeIconAttribute, size, ret) != B_OK) { - delete ret; - ret = NULL; + if (fNotification->Type() == B_PROGRESS_NOTIFICATION) { + font_height fh; + be_plain_font->GetHeight(&fh); + float fontHeight = fh.ascent + fh.descent + fh.leading; + size.height += (kSmallPadding * 2) + (kEdgePadding * 1) + fontHeight; } - return ret; -} - - -void -NotificationView::_LoadIcon() -{ - // First try to get the icon from the caller application - app_info info; - BMessenger msgr = fDetails->ReturnAddress(); - - if (msgr.IsValid()) - be_roster->GetRunningAppInfo(msgr.Team(), &info); - else if (fType == B_PROGRESS_NOTIFICATION) - be_roster->GetAppInfo("application/x-vnd.Haiku-notification_server", - &info); - - BPath path; - path.SetTo(&info.ref); - - fBitmap = _ReadNodeIcon(path.Path(), fParent->IconSize()); - if (fBitmap) - return; - - // If that failed get icons from app_server - if (find_directory(B_BEOS_SERVERS_DIRECTORY, &path) != B_OK) - return; - - path.Append("app_server"); - - BFile file(path.Path(), B_READ_ONLY); - if (file.InitCheck() != B_OK) - return; - - BResources res(&file); - if (res.InitCheck() != B_OK) - return; - - // Which one should we choose? - const char* iconName = ""; - switch (fType) { - case B_INFORMATION_NOTIFICATION: - iconName = "info"; - break; - case B_ERROR_NOTIFICATION: - iconName = "stop"; - break; - case B_IMPORTANT_NOTIFICATION: - iconName = "warn"; - break; - default: - return; - } - - // Allocate the bitmap - fBitmap = new BBitmap(BRect(0, 0, (float)B_LARGE_ICON - 1, - (float)B_LARGE_ICON - 1), B_RGBA32); - if (!fBitmap || fBitmap->InitCheck() != B_OK) { - fBitmap = NULL; - return; - } - - // Load raw icon data - size_t size = 0; - const uint8* data = (const uint8*)res.LoadResource(B_VECTOR_ICON_TYPE, - iconName, &size); - if ((data == NULL - || BIconUtils::GetVectorIcon(data, size, fBitmap) != B_OK)) - fBitmap = NULL; + return size; } diff --git a/src/servers/notification/NotificationView.h b/src/servers/notification/NotificationView.h index fb2fa071a9..46588a5e3b 100644 --- a/src/servers/notification/NotificationView.h +++ b/src/servers/notification/NotificationView.h @@ -11,15 +11,8 @@ #include <list> #include <Bitmap.h> -#include <Entry.h> -#include <Message.h> #include <MessageRunner.h> -#include <MimeType.h> #include <Notification.h> -#include <Path.h> -#include <Roster.h> -#include <String.h> -#include <TextView.h> #include <View.h> class NotificationWindow; @@ -29,39 +22,31 @@ const uint32 kRemoveView = 'ReVi'; class NotificationView : public BView { public: NotificationView(NotificationWindow* win, - notification_type type, - const char* app, const char* title, - const char* text, BMessage* details); + BNotification* notification, + bigtime_t timeout = -1); virtual ~NotificationView(); virtual void AttachedToWindow(); virtual void MessageReceived(BMessage* message); - virtual void GetPreferredSize(float* width, float* height); virtual void Draw(BRect updateRect); virtual void MouseDown(BPoint point); - virtual void FrameResized(float width, float height); + + virtual BSize MinSize(); + virtual BSize MaxSize(); + virtual BSize PreferredSize(); virtual BHandler* ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, int32 form, const char* property); virtual status_t GetSupportedSuites(BMessage* msg); - const char* Application() const; - const char* Title() const; - const char* Text() const; + void SetText(float newMaxWidth = -1); - void SetText(const char* app, const char* title, - const char* text, float newMaxWidth = -1); - bool HasMessageID(const char* id); - const char* MessageID(); - void SetPosition(bool first, bool last); + const char* MessageID() const; private: - BBitmap* _ReadNodeIcon(const char* fileName, - icon_size size); - void _LoadIcon(); + BSize _CalculateSize(); -private: struct LineInfo { BFont font; BString text; @@ -70,27 +55,17 @@ private: typedef std::list<LineInfo*> LineInfoList; - NotificationWindow* fParent; + BNotification* fNotification; + bigtime_t fTimeout; - notification_type fType; BMessageRunner* fRunner; - float fProgress; - BString fMessageID; - BMessage* fDetails; BBitmap* fBitmap; LineInfoList fLines; - BString fApp; - BString fTitle; - BString fText; - float fHeight; - - bool fIsFirst; - bool fIsLast; }; #endif // _NOTIFICATION_VIEW_H diff --git a/src/servers/notification/NotificationWindow.cpp b/src/servers/notification/NotificationWindow.cpp index 8c9c5032b0..059faa7a6c 100644 --- a/src/servers/notification/NotificationWindow.cpp +++ b/src/servers/notification/NotificationWindow.cpp @@ -19,15 +19,17 @@ #include <Alert.h> #include <Application.h> #include <Catalog.h> -#include <Debug.h> #include <File.h> +#include <GroupLayout.h> +#include <GroupLayoutBuilder.h> +#include <Layout.h> #include <NodeMonitor.h> +#include <Path.h> #include <PropertyInfo.h> #include <private/interface/WindowPrivate.h> #include "AppGroupView.h" #include "AppUsage.h" -#include "BorderView.h" #undef B_TRANSLATE_CONTEXT #define B_TRANSLATE_CONTEXT "NotificationWindow" @@ -54,23 +56,19 @@ const float kSmallPadding = 2; NotificationWindow::NotificationWindow() : - BWindow(BRect(0, 0, 0, 0), B_TRANSLATE_MARK("Notification"), + BWindow(BRect(0, 0, -1, -1), B_TRANSLATE_MARK("Notification"), B_BORDERED_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL, B_AVOID_FRONT | B_AVOID_FOCUS | B_NOT_CLOSABLE | B_NOT_ZOOMABLE | B_NOT_MINIMIZABLE - | B_NOT_RESIZABLE | B_NOT_MOVABLE, + | B_NOT_RESIZABLE | B_NOT_MOVABLE | B_AUTO_UPDATE_SIZE_LIMITS, B_ALL_WORKSPACES) { - fBorder = new BorderView(Bounds(), "Notification"); + SetLayout(new BGroupLayout(B_VERTICAL, 10)); - AddChild(fBorder); - - // Needed so everything gets the right size - we should switch to layout - // mode... - Show(); Hide(); + Show(); - LoadSettings(true); - LoadAppFilters(true); + _LoadSettings(true); + _LoadAppFilters(true); } @@ -101,7 +99,7 @@ NotificationWindow::WorkspaceActivated(int32 /*workspace*/, bool active) { // Ensure window is in the correct position if (active) - ResizeAll(); + _ResizeAll(); } @@ -111,13 +109,10 @@ NotificationWindow::MessageReceived(BMessage* message) switch (message->what) { case B_NODE_MONITOR: { - LoadSettings(); - LoadAppFilters(); + _LoadSettings(); + _LoadAppFilters(); break; } - case kResizeToFit: - ResizeAll(); - break; case B_COUNT_PROPERTIES: { BMessage reply(B_REPLY); @@ -145,60 +140,55 @@ NotificationWindow::MessageReceived(BMessage* message) case B_CREATE_PROPERTY: case kNotificationMessage: { - int32 type; - const char* content = NULL; - const char* title = NULL; - const char* app = NULL; BMessage reply(B_REPLY); - bool messageOkay = true; + BNotification* notification = new BNotification(message); - if (message->FindInt32("type", &type) != B_OK) - type = B_INFORMATION_NOTIFICATION; - if (message->FindString("content", &content) != B_OK) - messageOkay = false; - if (message->FindString("title", &title) != B_OK) - messageOkay = false; - if (message->FindString("app", &app) != B_OK - && message->FindString("appTitle", &app) != B_OK) - messageOkay = false; + if (notification->InitCheck() == B_OK) { + bigtime_t timeout; + if (message->FindInt64("timeout", &timeout) != B_OK) + timeout = -1; + BMessenger messenger = message->ReturnAddress(); + app_info info; + + if (messenger.IsValid()) + be_roster->GetRunningAppInfo(messenger.Team(), &info); + else + be_roster->GetAppInfo("application/x-vnd.Be-SHEL", &info); - if (messageOkay) { NotificationView* view = new NotificationView(this, - (notification_type)type, app, title, content, - new BMessage(*message)); + notification, timeout); - appfilter_t::iterator fIt = fAppFilters.find(app); bool allow = false; - if (fIt == fAppFilters.end()) { - app_info info; - BMessenger messenger = message->ReturnAddress(); - if (messenger.IsValid()) - be_roster->GetRunningAppInfo(messenger.Team(), &info); - else - be_roster->GetAppInfo("application/x-vnd.Be-SHEL", &info); + appfilter_t::iterator it = fAppFilters.find(info.signature); - AppUsage* appUsage = new AppUsage(info.ref, app, true); - fAppFilters[app] = appUsage; - - appUsage->Allowed(title, (notification_type)type); + if (it == fAppFilters.end()) { + AppUsage* appUsage = new AppUsage(notification->Group(), + true); + appUsage->Allowed(notification->Title(), + notification->Type()); + fAppFilters[info.signature] = appUsage; allow = true; - } else - allow = fIt->second->Allowed(title, (notification_type)type); + } else { + allow = it->second->Allowed(notification->Title(), + notification->Type()); + } if (allow) { - appview_t::iterator aIt = fAppViews.find(app); + BString groupName(notification->Group()); + appview_t::iterator aIt = fAppViews.find(groupName); AppGroupView* group = NULL; if (aIt == fAppViews.end()) { - group = new AppGroupView(this, app); - fAppViews[app] = group; - fBorder->AddChild(group); + group = new AppGroupView(this, + groupName == "" ? NULL : groupName.String()); + fAppViews[groupName] = group; + GetLayout()->AddView(group); } else group = aIt->second; group->AddInfo(view); - ResizeAll(); + _ResizeAll(); reply.AddInt32("error", B_OK); } else @@ -213,22 +203,16 @@ NotificationWindow::MessageReceived(BMessage* message) } case kRemoveView: { - void* _ptr; - message->FindPointer("view", &_ptr); + NotificationView* view = NULL; + if (message->FindPointer("view", (void**)&view) != B_OK) + return; - NotificationView* info - = reinterpret_cast<NotificationView*>(_ptr); + views_t::iterator it = find(fViews.begin(), fViews.end(), view); - fBorder->RemoveChild(info); + if (it != fViews.end()) + fViews.erase(it); - std::vector<NotificationView*>::iterator i - = find(fViews.begin(), fViews.end(), info); - if (i != fViews.end()) - fViews.erase(i); - - delete info; - - ResizeAll(); + _ResizeAll(); break; } default: @@ -297,22 +281,15 @@ NotificationWindow::Timeout() } -infoview_layout -NotificationWindow::Layout() -{ - return fLayout; -} - - float -NotificationWindow::ViewWidth() +NotificationWindow::Width() { return fWidth; } void -NotificationWindow::ResizeAll() +NotificationWindow::_ResizeAll() { if (fAppViews.empty()) { if (!IsHidden()) @@ -365,7 +342,7 @@ NotificationWindow::ResizeAll() } } - ResizeTo(ViewWidth(), height); + ResizeTo(Width(), height); PopupAnimation(); } @@ -429,14 +406,14 @@ NotificationWindow::PopupAnimation() { SetPosition(); - if (IsHidden() && fViews.size() != 0) + if (IsHidden()) Show(); // Activate();// it hides floaters from apps :-( } void -NotificationWindow::LoadSettings(bool startMonitor) +NotificationWindow::_LoadSettings(bool startMonitor) { _LoadGeneralSettings(startMonitor); _LoadDisplaySettings(startMonitor); @@ -444,7 +421,7 @@ NotificationWindow::LoadSettings(bool startMonitor) void -NotificationWindow::LoadAppFilters(bool startMonitor) +NotificationWindow::_LoadAppFilters(bool startMonitor) { BPath path; @@ -491,7 +468,7 @@ NotificationWindow::LoadAppFilters(bool startMonitor) void -NotificationWindow::SaveAppFilters() +NotificationWindow::_SaveAppFilters() { BPath path; @@ -543,7 +520,6 @@ NotificationWindow::_LoadGeneralSettings(bool startMonitor) views_t::iterator it; for (it = fViews.begin(); it != fViews.end(); ++it) { NotificationView* view = (*it); - view->SetText(view->Application(), view->Title(), view->Text()); view->Invalidate(); } @@ -589,26 +565,10 @@ NotificationWindow::_LoadDisplaySettings(bool startMonitor) else fIconSize = (icon_size)setting; - if (settings.FindInt32(kLayoutName, &setting) != B_OK) - fLayout = kDefaultLayout; - else { - switch (setting) { - case 0: - fLayout = TitleAboveIcon; - break; - case 1: - fLayout = AllTextRightOfIcon; - break; - default: - fLayout = kDefaultLayout; - } - } - // Notify the view about the change views_t::iterator it; for (it = fViews.begin(); it != fViews.end(); ++it) { NotificationView* view = (*it); - view->SetText(view->Application(), view->Title(), view->Text()); view->Invalidate(); } diff --git a/src/servers/notification/NotificationWindow.h b/src/servers/notification/NotificationWindow.h index 1d1658f402..9457ccf32d 100644 --- a/src/servers/notification/NotificationWindow.h +++ b/src/servers/notification/NotificationWindow.h @@ -26,8 +26,6 @@ class AppGroupView; class AppUsage; -class BorderView; -class SettingsFile; typedef std::map<BString, AppGroupView*> appview_t; typedef std::map<BString, AppUsage*> appfilter_t; @@ -39,8 +37,6 @@ extern const float kCloseSize; extern const float kExpandSize; extern const float kPenSize; -const uint32 kResizeToFit = 'IWrf'; - class NotificationWindow : public BWindow { public: NotificationWindow(); @@ -56,25 +52,22 @@ public: icon_size IconSize(); int32 Timeout(); - infoview_layout Layout(); - float ViewWidth(); + float Width(); - void ResizeAll(); + void _ResizeAll(); private: friend class AppGroupView; void SetPosition(); void PopupAnimation(); - void LoadSettings(bool startMonitor = false); - void LoadAppFilters(bool startMonitor = false); - void SaveAppFilters(); + void _LoadSettings(bool startMonitor = false); + void _LoadAppFilters(bool startMonitor = false); + void _SaveAppFilters(); void _LoadGeneralSettings(bool startMonitor); void _LoadDisplaySettings(bool startMonitor); views_t fViews; - BorderView* fBorder; - appview_t fAppViews; BString fStatusText; @@ -83,7 +76,6 @@ private: float fWidth; icon_size fIconSize; int32 fTimeout; - infoview_layout fLayout; appfilter_t fAppFilters; };