Added "Label as" Tracker add-on
Similar to the "Mark as" Tracker add-on, but for custom labels stored as files in ~/config/settings/Mail/labels. * Sets the MAIL:label file attribute. * The pop-up menu with all available labels also has an item to remove a currently set label from an email, and to open the labels folder to "Manage labels…" (add, remove, rename etc.). * Added File_Mail_label icon to distinguish from the "Mark as" add-on icon. It's supposed to be a narrow post-it as label… "Mark as" Tracker add-on: * Remove custom statuses from the "Mark as" Tracker add-on. That's what the new labels were introduced for. Change-Id: I912a747156da3538457f622c1e2b163700c0c7eb Reviewed-on: https://review.haiku-os.org/c/haiku/+/10539 Reviewed-by: nephele nephele <[email protected]>
This commit is contained in:
committed by
nephele nephele
parent
043ad4d92d
commit
fa0e6b2192
Binary file not shown.
@@ -2,6 +2,7 @@ SubDir HAIKU_TOP src add-ons tracker ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons tracker filetype ;
|
||||
SubInclude HAIKU_TOP src add-ons tracker iconvader ;
|
||||
SubInclude HAIKU_TOP src add-ons tracker label_as ;
|
||||
SubInclude HAIKU_TOP src add-ons tracker opentargetfolder ;
|
||||
SubInclude HAIKU_TOP src add-ons tracker mark_as ;
|
||||
SubInclude HAIKU_TOP src add-ons tracker openterminal ;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
SubDir HAIKU_TOP src add-ons tracker label_as ;
|
||||
|
||||
UsePrivateHeaders mail ;
|
||||
|
||||
AddResources Label\ as… : LabelAs.rdef ;
|
||||
|
||||
Addon Label\ as… :
|
||||
LabelAs.cpp
|
||||
: be tracker [ TargetLibsupc++ ] localestub
|
||||
;
|
||||
|
||||
DoCatalogs Label\ as… :
|
||||
x-vnd.Haiku-LabelAs
|
||||
:
|
||||
LabelAs.cpp
|
||||
;
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright 2026 Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <Catalog.h>
|
||||
#include <Collator.h>
|
||||
#include <Directory.h>
|
||||
#include <E-mail.h>
|
||||
#include <Entry.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Locale.h>
|
||||
#include <MenuItem.h>
|
||||
#include <Message.h>
|
||||
#include <Node.h>
|
||||
#include <ObjectList.h>
|
||||
#include <Path.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "Label-as add-on"
|
||||
|
||||
|
||||
BCollator collator;
|
||||
|
||||
|
||||
static int
|
||||
compare_menu_items(const BMenuItem* a, const BMenuItem* b)
|
||||
{
|
||||
return collator.Compare(a->Label(), b->Label());
|
||||
}
|
||||
|
||||
|
||||
static BPoint
|
||||
mouse_position()
|
||||
{
|
||||
BPoint position;
|
||||
get_mouse(&position, NULL);
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
open_labels_folder()
|
||||
{
|
||||
BPath path;
|
||||
find_directory(B_USER_SETTINGS_DIRECTORY, &path);
|
||||
path.Append("Mail/labels");
|
||||
|
||||
BEntry entry(path.Path());
|
||||
if (!entry.Exists())
|
||||
create_directory(path.Path(), 0777);
|
||||
|
||||
BEntry folderEntry;
|
||||
if (folderEntry.SetTo(path.Path()) == B_OK
|
||||
&& folderEntry.Exists()) {
|
||||
BMessage openFolderCommand(B_REFS_RECEIVED);
|
||||
BMessenger tracker("application/x-vnd.Be-TRAK");
|
||||
|
||||
entry_ref ref;
|
||||
folderEntry.GetRef(&ref);
|
||||
openFolderCommand.AddRef("refs", &ref);
|
||||
tracker.SendMessage(&openFolderCommand);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
retrieve_label_items(BMenu* menu)
|
||||
{
|
||||
menu->AddItem(new BMenuItem(B_TRANSLATE("Remove label"), NULL));
|
||||
menu->AddSeparatorItem();
|
||||
|
||||
BPath path;
|
||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
|
||||
return;
|
||||
|
||||
path.Append("Mail/labels");
|
||||
BDirectory directory(path.Path());
|
||||
BObjectList<BMenuItem> items;
|
||||
entry_ref ref;
|
||||
|
||||
while (directory.GetNextRef(&ref) == B_OK)
|
||||
items.AddItem(new BMenuItem(ref.name, NULL));
|
||||
|
||||
if (!items.IsEmpty()) {
|
||||
if (BLocale::Default()->GetCollator(&collator) == B_OK) {
|
||||
collator.SetNumericSorting(true);
|
||||
items.SortItems(compare_menu_items);
|
||||
}
|
||||
for (int32 i = 0; i < items.CountItems(); i++)
|
||||
menu->AddItem(items.ItemAt(i));
|
||||
menu->AddSeparatorItem();
|
||||
}
|
||||
menu->AddItem(new BMenuItem(B_TRANSLATE("Manage labels" B_UTF8_ELLIPSIS), NULL));
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
extern "C" void
|
||||
process_refs(entry_ref dir, BMessage* message, void* /*reserved*/)
|
||||
{
|
||||
BPopUpMenu* menu = new BPopUpMenu("labels");
|
||||
retrieve_label_items(menu);
|
||||
|
||||
BMenuItem* item = menu->Go(mouse_position() - BPoint(5, 5), false, true);
|
||||
if (item == NULL)
|
||||
return;
|
||||
|
||||
BString label = item->Label();
|
||||
entry_ref ref;
|
||||
for (int i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) {
|
||||
BNode node(&ref);
|
||||
BString type;
|
||||
BString previousLabel;
|
||||
if (node.InitCheck() == B_OK && node.ReadAttrString("BEOS:TYPE", &type) == B_OK
|
||||
&& (type == B_MAIL_TYPE || type == B_PARTIAL_MAIL_TYPE)) {
|
||||
if (label == B_TRANSLATE("Remove label"))
|
||||
node.RemoveAttr(B_MAIL_ATTR_LABEL);
|
||||
else if (label == B_TRANSLATE("Manage labels" B_UTF8_ELLIPSIS))
|
||||
open_labels_folder();
|
||||
else if (node.ReadAttrString(B_MAIL_ATTR_LABEL, &previousLabel) != B_OK
|
||||
|| previousLabel != label)
|
||||
node.WriteAttrString(B_MAIL_ATTR_LABEL, &label);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
resource app_signature "application/x-vnd.Haiku-LabelAs";
|
||||
|
||||
resource file_types message {
|
||||
"types" = "text/x-email",
|
||||
"types" = "text/x-partial-email"
|
||||
};
|
||||
|
||||
resource app_version {
|
||||
major = 1,
|
||||
middle = 0,
|
||||
minor = 0,
|
||||
|
||||
/* 0 = development 1 = alpha 2 = beta
|
||||
3 = gamma 4 = golden master 5 = final */
|
||||
variety = 0,
|
||||
|
||||
internal = 1,
|
||||
|
||||
short_info = "LabelAs, Copyright 2026 Haiku, Inc.",
|
||||
long_info = "A Tracker Add-on that marks emails with the chosen label."
|
||||
};
|
||||
|
||||
resource vector_icon {
|
||||
$"6E636966060500040167020006023A94CE3C078BBE370C3CD1394B9EF94A1372"
|
||||
$"00FAF9D2FFDDDB8F03FF0000020006023AC26B3A272ABB621E3C2B0B4A03F64A"
|
||||
$"005700010101FF807E5D020006033959AFBA52CE3AE8E03A190A49C920491610"
|
||||
$"2F67CBFFA80594DDFD1BAFFB070A04495D4C5E604A5C480A04363A5C49485D22"
|
||||
$"4A0A044F464A4B504E55490802384244480802BB11C23D3E4B0802B946C3AF3E"
|
||||
$"510606AE0B383D4434BFC9BB81C22FBAAD46314D33C41EBBC74D354936404008"
|
||||
$"0A010100000A0001011001178402040A020101000A030102000A040303040510"
|
||||
$"01178100040A00010630242201178300040A0501062024220A00001001178200"
|
||||
$"04"
|
||||
};
|
||||
|
||||
@@ -48,31 +48,6 @@ add_status_item(BMenu* menu, const char* name)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
retrieve_status_items(BMenu* menu)
|
||||
{
|
||||
BPath path;
|
||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
|
||||
return;
|
||||
|
||||
path.Append("Mail/status");
|
||||
|
||||
BDirectory directory(path.Path());
|
||||
|
||||
entry_ref ref;
|
||||
while (directory.GetNextRef(&ref) == B_OK) {
|
||||
if (!strcmp(ref.name, ".") || !strcmp(ref.name, ".."))
|
||||
continue;
|
||||
|
||||
add_status_item(menu, ref.name);
|
||||
}
|
||||
|
||||
add_status_item(menu, "New");
|
||||
add_status_item(menu, "Read");
|
||||
add_status_item(menu, "Replied");
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
@@ -80,7 +55,9 @@ extern "C" void
|
||||
process_refs(entry_ref dir, BMessage* message, void* /*reserved*/)
|
||||
{
|
||||
BPopUpMenu* menu = new BPopUpMenu("status");
|
||||
retrieve_status_items(menu);
|
||||
add_status_item(menu, "New");
|
||||
add_status_item(menu, "Read");
|
||||
add_status_item(menu, "Replied");
|
||||
|
||||
BMenuItem* item = menu->Go(mouse_position() - BPoint(5, 5), false, true);
|
||||
if (item == NULL)
|
||||
|
||||
Reference in New Issue
Block a user