BPicture: Fix archive constructor.
[haiku.git] / src / kits / app / Notification.cpp
blob7f383641a2a48edf8a52ade849df1ae9d0bb703c
1 /*
2 * Copyright 2010, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
7 * Stephan Aßmus, superstippi@gmx.de
8 */
11 #include <Notification.h>
13 #include <new>
15 #include <stdlib.h>
16 #include <string.h>
18 #include <notification/Notifications.h>
20 #include <Bitmap.h>
21 #include <Message.h>
24 BNotification::BNotification(notification_type type)
26 BArchivable(),
27 fInitStatus(B_OK),
28 fType(type),
29 fProgress(0.f),
30 fFile(NULL),
31 fBitmap(NULL)
36 BNotification::BNotification(BMessage* archive)
38 BArchivable(archive),
39 fInitStatus(B_OK),
40 fProgress(0.0f),
41 fFile(NULL),
42 fBitmap(NULL)
44 int32 type;
45 if (archive->FindInt32("_type", &type) == B_OK)
46 fType = (notification_type)type;
47 else
48 fInitStatus = B_ERROR;
50 BString group;
51 if (archive->FindString("_group", &group) == B_OK)
52 SetGroup(group);
54 BString title;
55 if (archive->FindString("_title", &title) == B_OK)
56 SetTitle(title);
58 BString content;
59 if (archive->FindString("_content", &content) == B_OK)
60 SetContent(content);
62 BString messageID;
63 if (archive->FindString("_messageID", &messageID) == B_OK)
64 SetMessageID(messageID);
66 float progress;
67 if (type == B_PROGRESS_NOTIFICATION
68 && archive->FindFloat("_progress", &progress) == B_OK)
69 SetProgress(progress);
71 BString onClickApp;
72 if (archive->FindString("_onClickApp", &onClickApp) == B_OK)
73 SetOnClickApp(onClickApp);
75 entry_ref onClickFile;
76 if (archive->FindRef("_onClickFile", &onClickFile) == B_OK)
77 SetOnClickFile(&onClickFile);
79 entry_ref onClickRef;
80 int32 index = 0;
81 while (archive->FindRef("_onClickRef", index++, &onClickRef) == B_OK)
82 AddOnClickRef(&onClickRef);
84 BString onClickArgv;
85 index = 0;
86 while (archive->FindString("_onClickArgv", index++, &onClickArgv) == B_OK)
87 AddOnClickArg(onClickArgv);
89 status_t ret = B_OK;
90 BMessage icon;
91 if ((ret = archive->FindMessage("_icon", &icon)) == B_OK) {
92 BBitmap bitmap(&icon);
93 ret = bitmap.InitCheck();
94 if (ret == B_OK)
95 ret = SetIcon(&bitmap);
100 BNotification::~BNotification()
102 delete fFile;
103 delete fBitmap;
105 for (int32 i = fRefs.CountItems() - 1; i >= 0; i--)
106 delete (entry_ref*)fRefs.ItemAtFast(i);
108 for (int32 i = fArgv.CountItems() - 1; i >= 0; i--)
109 free(fArgv.ItemAtFast(i));
113 /*! \brief Returns initialization status.
115 status_t
116 BNotification::InitCheck() const
118 return fInitStatus;
122 /*! \brief Returns a new BNotification object from @archive.
124 Returns a new BNotification object, allocated by new and created
125 with the version of the constructor that takes BMessage archive.
126 However, if the message doesn't contain an archived data for a
127 BNotification object, this method returns NULL.
129 \return BNotification object from @archive or NULL if it doesn't
130 contain a valid BNotification object.
132 BArchivable*
133 BNotification::Instantiate(BMessage* archive)
135 if (validate_instantiation(archive, "BNotification"))
136 return new(std::nothrow) BNotification(archive);
138 return NULL;
142 /*! \brief Archives the BNotification in the BMessages @archive.
144 \sa BArchivable::Archive(), Instantiate() static function.
145 \return
146 - \c B_OK: Everything went fine.
147 - \c Other errors: Archiving has failed.
149 status_t
150 BNotification::Archive(BMessage* archive, bool deep) const
152 status_t status = BArchivable::Archive(archive, deep);
154 if (status == B_OK)
155 status = archive->AddInt32("_type", (int32)fType);
157 if (status == B_OK && Group() != NULL)
158 status = archive->AddString("_group", Group());
160 if (status == B_OK && Title() != NULL)
161 status = archive->AddString("_title", Title());
163 if (status == B_OK && Content() != NULL)
164 status = archive->AddString("_content", Content());
166 if (status == B_OK && MessageID() != NULL)
167 status = archive->AddString("_messageID", MessageID());
169 if (status == B_OK && Type() == B_PROGRESS_NOTIFICATION)
170 status = archive->AddFloat("_progress", Progress());
172 if (status == B_OK && OnClickApp() != NULL)
173 status = archive->AddString("_onClickApp", OnClickApp());
175 if (status == B_OK && OnClickFile() != NULL)
176 status = archive->AddRef("_onClickFile", OnClickFile());
178 if (status == B_OK) {
179 for (int32 i = 0; i < CountOnClickRefs(); i++) {
180 status = archive->AddRef("_onClickRef", OnClickRefAt(i));
181 if (status != B_OK)
182 break;
186 if (status == B_OK) {
187 for (int32 i = 0; i < CountOnClickArgs(); i++) {
188 status = archive->AddString("_onClickArgv", OnClickArgAt(i));
189 if (status != B_OK)
190 break;
194 if (status == B_OK) {
195 const BBitmap* icon = Icon();
196 if (icon != NULL) {
197 BMessage iconArchive;
198 status = icon->Archive(&iconArchive);
199 if (status == B_OK)
200 archive->AddMessage("_icon", &iconArchive);
204 return status;
208 /*! \brief Notification's type.
210 \return A value of the notification_type enum that represents
211 notification type.
213 notification_type
214 BNotification::Type() const
216 return fType;
220 /*! \brief Returns notification's group.
222 \return Notification's group.
224 const char*
225 BNotification::Group() const
227 if (fGroup == "")
228 return NULL;
229 return fGroup;
233 /*! \brief Sets notification's group.
235 Notifications can be grouped together setting the same group.
237 void
238 BNotification::SetGroup(const BString& group)
240 fGroup = group;
244 /*! \brief Returns notification's title.
246 \return Notification's title.
248 const char*
249 BNotification::Title() const
251 if (fTitle == "")
252 return NULL;
253 return fTitle;
257 /*! \brief Set notification's title.
259 void
260 BNotification::SetTitle(const BString& title)
262 fTitle = title;
266 /*! \brief Returns notification's message.
268 \return Notification's message.
270 const char*
271 BNotification::Content() const
273 if (fContent == "")
274 return NULL;
275 return fContent;
279 /*! \brief Sets notification's message.
281 void
282 BNotification::SetContent(const BString& content)
284 fContent = content;
288 /*! \brief Returns notification's message identifier.
290 \return Notification's message identifier.
292 const char*
293 BNotification::MessageID() const
295 if (fID == "")
296 return NULL;
297 return fID;
301 /*! \brief Sets notification's message identifier.
303 void
304 BNotification::SetMessageID(const BString& id)
306 fID = id;
310 /*! \brief Returns progress information.
312 If notification's type is \c B_PROGRESS_NOTIFICATION, returns a value
313 between 0.0 and 1.0 that represent progress percentage.
315 If notification's type is not \c B_PROGRESS_NOTIFICATION, returns -1.
317 \return Percentage if notification's type is B_PROGRESS_NOTIFICATION
318 or otherwise -1.
320 float
321 BNotification::Progress() const
323 if (fType != B_PROGRESS_NOTIFICATION)
324 return -1;
325 return fProgress;
329 /*! \brief Sets progress information.
331 Sets progress percentage, this information will be used only
332 if notification's type is \c B_PROGRESS_NOTIFICATION.
334 The value of @progress must be between 0.0 and 1.0.
336 void
337 BNotification::SetProgress(float progress)
339 if (progress < 0)
340 fProgress = 0;
341 else if (progress > 1)
342 fProgress = 1;
343 else
344 fProgress = progress;
348 const char*
349 BNotification::OnClickApp() const
351 if (fApp == "")
352 return NULL;
353 return fApp;
357 void
358 BNotification::SetOnClickApp(const BString& app)
360 fApp = app;
364 const entry_ref*
365 BNotification::OnClickFile() const
367 return fFile;
371 status_t
372 BNotification::SetOnClickFile(const entry_ref* file)
374 delete fFile;
376 if (file != NULL) {
377 fFile = new(std::nothrow) entry_ref(*file);
378 if (fFile == NULL)
379 return B_NO_MEMORY;
380 } else
381 fFile = NULL;
383 return B_OK;
387 status_t
388 BNotification::AddOnClickRef(const entry_ref* ref)
390 if (ref == NULL)
391 return B_BAD_VALUE;
393 entry_ref* clonedRef = new(std::nothrow) entry_ref(*ref);
394 if (clonedRef == NULL || !fRefs.AddItem(clonedRef))
395 return B_NO_MEMORY;
397 return B_OK;
401 int32
402 BNotification::CountOnClickRefs() const
404 return fRefs.CountItems();
408 const entry_ref*
409 BNotification::OnClickRefAt(int32 index) const
411 return (entry_ref*)fArgv.ItemAt(index);
415 status_t
416 BNotification::AddOnClickArg(const BString& arg)
418 char* clonedArg = strdup(arg.String());
419 if (clonedArg == NULL || !fArgv.AddItem(clonedArg))
420 return B_NO_MEMORY;
422 return B_OK;
426 int32
427 BNotification::CountOnClickArgs() const
429 return fArgv.CountItems();
433 const char*
434 BNotification::OnClickArgAt(int32 index) const
436 return (char*)fArgv.ItemAt(index);
440 /*! \brief Notification's icon.
442 \return Notification's icon.
444 const BBitmap*
445 BNotification::Icon() const
447 return fBitmap;
451 /*! \brief Sets notification's icon.
453 Sets notification's icon.
454 This method does not assume ownership of @icon.
456 \param icon Icon
457 \return
458 - \c B_OK: Everything went fine.
459 - \c B_NO_MEMORY: Allocation of @icon copy has failed.
460 - \c Other errors: Creation of @icon copy failed for some reason.
462 status_t
463 BNotification::SetIcon(const BBitmap* icon)
465 delete fBitmap;
467 if (icon != NULL) {
468 fBitmap = new(std::nothrow) BBitmap(icon);
469 if (fBitmap == NULL)
470 return B_NO_MEMORY;
471 return fBitmap->InitCheck();
474 fBitmap = NULL;
475 return B_OK;
479 /*! \brief Sends a notification to the notification_server.
481 The notification is delivered asynchronously to the notification_server,
482 which will display it according to its settings and filters.
484 \param timeout Microseconds after the message fades out.
485 \return
486 - \c B_OK: Everything went fine.
487 - \c B_BAD_PORT_ID: A connection to notification_server could not be
488 established or the server is not up and running anymore.
489 - \c Other errors: Building the message from the notification failed.
491 status_t
492 BNotification::Send(bigtime_t timeout)
494 BMessage msg(kNotificationMessage);
496 // Archive notification
497 status_t ret = Archive(&msg);
499 // Custom time out
500 if (ret == B_OK && timeout > 0)
501 ret = msg.AddInt64("timeout", timeout);
503 // Send message
504 if (ret == B_OK) {
505 BMessenger server(kNotificationServerSignature);
506 ret = server.SendMessage(&msg);
509 return ret;