xref: /haiku/src/add-ons/tracker/mark_as/MarkAs.cpp (revision 45bd7bb3db9d9e4dcb02b89a3e7c2bf382c0a88c)
1 /*
2  * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <new>
8 
9 #include <Directory.h>
10 #include <Entry.h>
11 #include <FindDirectory.h>
12 #include <InterfaceDefs.h>
13 #include <MenuItem.h>
14 #include <Message.h>
15 #include <Node.h>
16 #include <Path.h>
17 #include <PopUpMenu.h>
18 #include <String.h>
19 
20 
21 static BPoint
22 mouse_position()
23 {
24 	// Returns the mouse position in screen coordinates
25 	BPoint position;
26 	get_mouse(&position, NULL);
27 	return position;
28 }
29 
30 
31 static void
32 add_status_item(BMenu* menu, const char* name)
33 {
34 	if (menu->FindItem(name) != NULL)
35 		return;
36 
37 	// Sort items alphabetically
38 	int32 index;
39 	for (index = 0; index < menu->CountItems(); index++) {
40 		if (strcmp(menu->ItemAt(index)->Label(), name) > 0)
41 			break;
42 	}
43 
44 	menu->AddItem(new BMenuItem(name, NULL), index);
45 }
46 
47 
48 static void
49 retrieve_status_items(BMenu* menu)
50 {
51 	BPath path;
52 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
53 		return;
54 
55 	path.Append("Mail/status");
56 
57 	BDirectory directory(path.Path());
58 
59 	entry_ref ref;
60 	while (directory.GetNextRef(&ref) == B_OK) {
61 		if (!strcmp(ref.name, ".") || !strcmp(ref.name, ".."))
62 			continue;
63 
64 		add_status_item(menu, ref.name);
65 	}
66 
67 	add_status_item(menu, "New");
68 	add_status_item(menu, "Read");
69 	add_status_item(menu, "Replied");
70 }
71 
72 
73 // #pragma mark -
74 
75 
76 extern "C" void
77 process_refs(entry_ref dir, BMessage* message, void* /*reserved*/)
78 {
79 	BPopUpMenu* menu = new BPopUpMenu("status");
80 	retrieve_status_items(menu);
81 
82 	BMenuItem* item = menu->Go(mouse_position() - BPoint(5, 5), false, true);
83 	if (item == NULL)
84 		return;
85 
86 	BString status = item->Label();
87 
88 	entry_ref ref;
89 	for (int i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) {
90 		BNode node(&ref);
91 		BString type;
92 
93 		if (node.InitCheck() == B_OK
94 			&& node.ReadAttrString("BEOS:TYPE", &type) == B_OK
95 			&& type == "text/x-email") {
96 			BString previousStatus;
97 
98 			// Only update the attribute if there is an actual change
99 			if (node.ReadAttrString("MAIL:status", &previousStatus) != B_OK
100 				|| previousStatus != status)
101 				node.WriteAttrString("MAIL:status", &status);
102 		}
103 	}
104 }
105 
106