mirror of
https://review.haiku-os.org/haiku
synced 2025-02-08 22:58:18 +01:00
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
299 lines
7.0 KiB
C++
299 lines
7.0 KiB
C++
/*
|
|
* Copyright 2010, Haiku, Inc. All rights reserved.
|
|
* Copyright 2008, Pier Luigi Fiorini.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
|
|
* Stephan Aßmus <superstippi@gmx.de>
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <Application.h>
|
|
#include <Bitmap.h>
|
|
#include <IconUtils.h>
|
|
#include <List.h>
|
|
#include <Mime.h>
|
|
#include <Notification.h>
|
|
#include <Path.h>
|
|
#include <TranslationUtils.h>
|
|
|
|
const char* kSignature = "application/x-vnd.Haiku-notify";
|
|
const char* kSmallIconAttribute = "BEOS:M:STD_ICON";
|
|
const char* kLargeIconAttribute = "BEOS:L:STD_ICON";
|
|
const char* kIconAttribute = "BEOS:ICON";
|
|
|
|
const char *kTypeNames[] = {
|
|
"information",
|
|
"important",
|
|
"error",
|
|
"progress",
|
|
NULL
|
|
};
|
|
|
|
const int32 kErrorInitFail = 127;
|
|
const int32 kErrorArgumentsFail = 126;
|
|
|
|
class NotifyApp : public BApplication {
|
|
public:
|
|
NotifyApp();
|
|
virtual ~NotifyApp();
|
|
|
|
virtual void ReadyToRun();
|
|
virtual void ArgvReceived(int32 argc, char** argv);
|
|
|
|
bool HasGoodArguments() const
|
|
{ return fHasGoodArguments; }
|
|
|
|
private:
|
|
bool fHasGoodArguments;
|
|
notification_type fType;
|
|
BString fGroup;
|
|
BString fTitle;
|
|
BString fMsgId;
|
|
float fProgress;
|
|
bigtime_t fTimeout;
|
|
BString fIconFile;
|
|
entry_ref fFileRef;
|
|
BString fContent;
|
|
BString fOnClickApp;
|
|
bool fHasFile;
|
|
entry_ref fFile;
|
|
BList* fRefs;
|
|
BList* fArgv;
|
|
|
|
void _Usage() const;
|
|
BBitmap* _GetBitmap(const entry_ref* ref) const;
|
|
};
|
|
|
|
|
|
NotifyApp::NotifyApp()
|
|
:
|
|
BApplication(kSignature),
|
|
fHasGoodArguments(false),
|
|
fType(B_INFORMATION_NOTIFICATION),
|
|
fProgress(0.0f),
|
|
fTimeout(-1),
|
|
fHasFile(false)
|
|
{
|
|
fRefs = new BList();
|
|
fArgv = new BList();
|
|
}
|
|
|
|
|
|
NotifyApp::~NotifyApp()
|
|
{
|
|
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++)
|
|
delete (BString*)item;
|
|
delete fArgv;
|
|
}
|
|
|
|
|
|
void
|
|
NotifyApp::ArgvReceived(int32 argc, char** argv)
|
|
{
|
|
const uint32 kArgCount = argc - 1;
|
|
uint32 index = 1;
|
|
|
|
// Look for valid options
|
|
for (; index <= kArgCount; ++index) {
|
|
if (argv[index][0] == '-' && argv[index][1] == '-') {
|
|
const char* option = argv[index] + 2;
|
|
|
|
if (++index > kArgCount) {
|
|
// No argument to option
|
|
fprintf(stderr, "Missing argument to option --%s\n\n", option);
|
|
return;
|
|
}
|
|
|
|
const char* argument = argv[index];
|
|
|
|
if (strcmp(option, "type") == 0) {
|
|
for (int32 i = 0; kTypeNames[i]; i++) {
|
|
if (strncmp(kTypeNames[i], argument, strlen(argument)) == 0)
|
|
fType = (notification_type)i;
|
|
}
|
|
} else if (strcmp(option, "group") == 0)
|
|
fGroup = argument;
|
|
else if (strcmp(option, "title") == 0)
|
|
fTitle = argument;
|
|
else if (strcmp(option, "messageID") == 0)
|
|
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 = argument;
|
|
|
|
if (get_ref_for_path(fIconFile.String(), &fFileRef) < B_OK) {
|
|
fprintf(stderr, "Bad icon path!\n\n");
|
|
return;
|
|
}
|
|
} else if (strcmp(option, "onClickApp") == 0)
|
|
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");
|
|
return;
|
|
}
|
|
|
|
fHasFile = true;
|
|
} else if (strcmp(option, "onClickRef") == 0) {
|
|
entry_ref ref;
|
|
|
|
if (get_ref_for_path(argument, &ref) != B_OK) {
|
|
fprintf(stderr, "Bad path for --onClickRef!\n\n");
|
|
return;
|
|
}
|
|
|
|
fRefs->AddItem(new BEntry(&ref));
|
|
} else if (strcmp(option, "onClickArgv") == 0)
|
|
fArgv->AddItem(new BString(argument));
|
|
else {
|
|
// Unrecognized option
|
|
fprintf(stderr, "Unrecognized option --%s\n\n", option);
|
|
return;
|
|
}
|
|
} else {
|
|
// Option doesn't start with '--'
|
|
break;
|
|
}
|
|
|
|
if (index == kArgCount) {
|
|
// No text argument provided, only '--' arguments
|
|
fprintf(stderr, "Missing message argument!\n\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
fContent = argv[index];
|
|
fHasGoodArguments = true;
|
|
}
|
|
|
|
void
|
|
NotifyApp::_Usage() const
|
|
{
|
|
fprintf(stderr, "Usage: notify [OPTION]... [MESSAGE]\n"
|
|
"Send notifications to notification_server.\n"
|
|
" --type <type>\tNotification type,\n"
|
|
" \t <type> - \"information\" is assumed by default: ");
|
|
|
|
for (int32 i = 0; kTypeNames[i]; i++)
|
|
fprintf(stderr, kTypeNames[i + 1] ? "%s|" : "%s\n", kTypeNames[i]);
|
|
|
|
fprintf(stderr,
|
|
" --group <group>\tGroup\n"
|
|
" --title <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"
|
|
" --timeout <secs>\tSpecify timeout\n"
|
|
" --onClickApp <signature>\tApplication to open when notification is clicked\n"
|
|
" --onClickFile <fullpath>\tFile to open when notification is clicked\n"
|
|
" --onClickRef <fullpath>\tFile to open with the application when notification is clicked\n"
|
|
" --onClickArgv <arg>\tArgument to the application when notification is clicked\n"
|
|
" --icon <icon file> Icon\n");
|
|
}
|
|
|
|
|
|
BBitmap*
|
|
NotifyApp::_GetBitmap(const entry_ref* ref) const
|
|
{
|
|
BBitmap* bitmap = NULL;
|
|
|
|
// First try by contents
|
|
bitmap = BTranslationUtils::GetBitmap(ref);
|
|
if (bitmap)
|
|
return bitmap;
|
|
|
|
// Then, try reading its attribute
|
|
BNode node(BPath(ref).Path());
|
|
bitmap = new BBitmap(BRect(0, 0, (float)B_LARGE_ICON - 1,
|
|
(float)B_LARGE_ICON - 1), B_RGBA32);
|
|
if (BIconUtils::GetIcon(&node, kIconAttribute, kSmallIconAttribute,
|
|
kLargeIconAttribute, B_LARGE_ICON, bitmap) != B_OK) {
|
|
delete bitmap;
|
|
bitmap = NULL;
|
|
}
|
|
|
|
return bitmap;
|
|
}
|
|
|
|
|
|
void
|
|
NotifyApp::ReadyToRun()
|
|
{
|
|
if (HasGoodArguments()) {
|
|
BNotification notification(fType);
|
|
if (fGroup != "")
|
|
notification.SetGroup(fGroup);
|
|
if (fTitle != "")
|
|
notification.SetTitle(fTitle);
|
|
if (fContent != "")
|
|
notification.SetContent(fContent);
|
|
|
|
if (fMsgId != "")
|
|
notification.SetMessageID(fMsgId);
|
|
|
|
if (fType == B_PROGRESS_NOTIFICATION)
|
|
notification.SetProgress(fProgress);
|
|
|
|
if (fIconFile != "") {
|
|
BBitmap* bitmap = _GetBitmap(&fFileRef);
|
|
if (bitmap) {
|
|
notification.SetIcon(bitmap);
|
|
delete bitmap;
|
|
}
|
|
}
|
|
|
|
if (fOnClickApp != "")
|
|
notification.SetOnClickApp(fOnClickApp);
|
|
|
|
if (fHasFile)
|
|
notification.SetOnClickFile(&fFile);
|
|
|
|
for (int32 i = 0; void* item = fRefs->ItemAt(i); i++) {
|
|
BEntry* entry = (BEntry*)item;
|
|
|
|
entry_ref ref;
|
|
if (entry->GetRef(&ref) == B_OK)
|
|
notification.AddOnClickRef(&ref);
|
|
}
|
|
|
|
for (int32 i = 0; void* item = fArgv->ItemAt(i); i++) {
|
|
BString* arg = (BString*)item;
|
|
notification.AddOnClickArg(arg->String());
|
|
}
|
|
|
|
status_t ret = notification.Send(fTimeout);
|
|
if (ret != B_OK) {
|
|
fprintf(stderr, "Failed to deliver notification: %s\n",
|
|
strerror(ret));
|
|
}
|
|
} else
|
|
_Usage();
|
|
|
|
Quit();
|
|
}
|
|
|
|
|
|
int
|
|
main(int argc, char** argv)
|
|
{
|
|
NotifyApp app;
|
|
if (app.InitCheck() != B_OK)
|
|
return kErrorInitFail;
|
|
|
|
app.Run();
|
|
if (!app.HasGoodArguments())
|
|
return kErrorArgumentsFail;
|
|
|
|
return 0;
|
|
}
|