Mail app: Implement labeling emails
"Labels" (MAIL:label) will be used instead of the currently misused "Status" (MAIL:status) to allow categorization of emails by the user. These labels are only used on the locally download emails; there's no syncing with a mail server. (See also forum thread "Introducing a new indexed attribute META:tag" at https://discuss.haiku-os.org/t/introducing-a-new-indexed-attribute-meta-tag.) * Remove custom statuses from "Close and…" submenu and anything else concerning custom statuses. * Add a "Set label" menu with a submenu to - Remove the current mail's label, if it has one - Add a new label - Choose from a list of labels (first 9 items with ALT+n shortcut) - Open the labels folder in Tracker to manage labels (delete/rename/etc.) * Labels are saved as separate files in ~/config/settings/Mail/labels/ * Label files are queries for all files which have that particular label in their MAIL:label attribute. This is convenient when managing your label, e.g. see if there are any emails with a certain label before deleting it. * Added "Same label" to the "Queries" menu. * In MenusBeginning() the files in ~/config/settings/Mail/labels/ are read and shown with their file name as menu item. * When an email is opened, its label file is created if it doesn't exist already. That way the Mail app can provide labels that were not created with it, but e.g. by manually filling the attribute in Tracker, or via a script etc. * Related: When populating the labels menu, make sure each label query has the correct formula. A user may have created a label by hand or duplicated an existing formula, in which case the query formula would be missing or wrong. Setting a label currently isn't supported when composing an email, as we cannot set an attribute, because an email file isn't created until it's sent. Change-Id: I53fb4613ec1d2d96493169e0310c11c5ba0131c2 Reviewed-on: https://review.haiku-os.org/c/haiku/+/10384 Tested-by: Commit checker robot <[email protected]> Reviewed-by: humdinger humdinger <[email protected]>
This commit is contained in:
committed by
humdinger humdinger
parent
640b37b32d
commit
e53d371901
@@ -16,6 +16,7 @@ Application Mail :
|
||||
Enclosures.cpp
|
||||
FindWindow.cpp
|
||||
Header.cpp
|
||||
LabelWindow.cpp
|
||||
MailApp.cpp
|
||||
MailPopUpMenu.cpp
|
||||
MailSupport.cpp
|
||||
@@ -26,7 +27,6 @@ Application Mail :
|
||||
QueryList.cpp
|
||||
QueryMenu.cpp
|
||||
Signature.cpp
|
||||
Status.cpp
|
||||
Utilities.cpp
|
||||
WIndex.cpp
|
||||
Words.cpp
|
||||
@@ -50,6 +50,7 @@ DoCatalogs Mail :
|
||||
Enclosures.cpp
|
||||
FindWindow.cpp
|
||||
Header.cpp
|
||||
LabelWindow.cpp
|
||||
LocalizedFolders.h
|
||||
MailApp.cpp
|
||||
MailPopUpMenu.cpp
|
||||
@@ -57,5 +58,4 @@ DoCatalogs Mail :
|
||||
Prefs.cpp
|
||||
Settings.cpp
|
||||
Signature.cpp
|
||||
Status.cpp
|
||||
;
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2026 Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "LabelWindow.h"
|
||||
|
||||
#include <Button.h>
|
||||
#include <Catalog.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <TextControl.h>
|
||||
|
||||
#include "MailSupport.h"
|
||||
#include "Messages.h"
|
||||
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "LabelWindow"
|
||||
|
||||
|
||||
enum _messages {
|
||||
kLabel = 128,
|
||||
kOK,
|
||||
kCancel
|
||||
};
|
||||
|
||||
|
||||
TLabelWindow::TLabelWindow(BRect frame, BMessenger target)
|
||||
: BWindow(BRect(), "", B_MODAL_WINDOW, B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS),
|
||||
fTarget(target)
|
||||
{
|
||||
fLabel = new BTextControl("label", B_TRANSLATE("New label:"), "", NULL);
|
||||
fLabel->SetModificationMessage(new BMessage(kLabel));
|
||||
// disallow control characters and "/"
|
||||
for (uint32 i = 0; i < 0x20; ++i)
|
||||
fLabel->TextView()->DisallowChar(i);
|
||||
fLabel->TextView()->DisallowChar('/');
|
||||
|
||||
fOK = new BButton("ok", B_TRANSLATE("OK"), new BMessage(kOK));
|
||||
fOK->MakeDefault(true);
|
||||
fOK->SetEnabled(false);
|
||||
|
||||
BButton *cancel = new BButton("cancel", B_TRANSLATE("Cancel"), new BMessage(kCancel));
|
||||
|
||||
BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
|
||||
.SetInsets(B_USE_DEFAULT_SPACING)
|
||||
.AddGroup(B_HORIZONTAL, 0)
|
||||
.Add(fLabel)
|
||||
.End()
|
||||
.AddStrut(B_USE_SMALL_SPACING)
|
||||
.AddGroup(B_HORIZONTAL, B_USE_SMALL_SPACING, 0)
|
||||
.AddStrut(B_USE_SMALL_SPACING)
|
||||
.Add(cancel)
|
||||
.Add(fOK);
|
||||
|
||||
fLabel->BTextControl::MakeFocus(true);
|
||||
CenterIn(frame);
|
||||
Show();
|
||||
}
|
||||
|
||||
|
||||
TLabelWindow::~TLabelWindow()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TLabelWindow::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case kLabel:
|
||||
fOK->SetEnabled(true);
|
||||
break;
|
||||
|
||||
case kOK:
|
||||
{
|
||||
const char* newLabel = fLabel->Text();
|
||||
if (create_label_file(newLabel) == B_OK) {
|
||||
BMessage message(M_SET_LABEL);
|
||||
message.AddString("label", newLabel);
|
||||
fTarget.SendMessage(&message);
|
||||
}
|
||||
// intentional fall-through
|
||||
}
|
||||
case kCancel:
|
||||
Quit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2026 Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _LABELWINDOW_H
|
||||
#define _LABELWINDOW_H
|
||||
|
||||
|
||||
#include <Messenger.h>
|
||||
#include <Window.h>
|
||||
|
||||
class BTextControl;
|
||||
|
||||
|
||||
class TLabelWindow : public BWindow {
|
||||
public:
|
||||
TLabelWindow(BRect frame, BMessenger target);
|
||||
virtual ~TLabelWindow();
|
||||
|
||||
protected:
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
private:
|
||||
BButton* fOK;
|
||||
BMessenger fTarget;
|
||||
BTextControl* fLabel;
|
||||
};
|
||||
|
||||
#endif // #ifndef _LABELWINDOW_H
|
||||
|
||||
@@ -76,13 +76,13 @@ using namespace BPrivate ;
|
||||
#include "FieldMsg.h"
|
||||
#include "FindWindow.h"
|
||||
#include "Header.h"
|
||||
#include "LabelWindow.h"
|
||||
#include "MailSupport.h"
|
||||
#include "MailWindow.h"
|
||||
#include "Messages.h"
|
||||
#include "Prefs.h"
|
||||
#include "QueryMenu.h"
|
||||
#include "Signature.h"
|
||||
#include "Status.h"
|
||||
#include "String.h"
|
||||
#include "Utilities.h"
|
||||
#include "Words.h"
|
||||
@@ -470,7 +470,7 @@ void
|
||||
TMailApp::ReadyToRun()
|
||||
{
|
||||
// Create needed indices for META:group, META:email, MAIL:draft,
|
||||
// INDEX_SIGNATURE, INDEX_STATUS on the boot volume
|
||||
// INDEX_SIGNATURE on the boot volume
|
||||
|
||||
BVolume volume;
|
||||
BVolumeRoster().GetBootVolume(&volume);
|
||||
@@ -479,7 +479,6 @@ TMailApp::ReadyToRun()
|
||||
fs_create_index(volume.Device(), "META:email", B_STRING_TYPE, 0);
|
||||
fs_create_index(volume.Device(), "MAIL:draft", B_INT32_TYPE, 0);
|
||||
fs_create_index(volume.Device(), INDEX_SIGNATURE, B_STRING_TYPE, 0);
|
||||
fs_create_index(volume.Device(), INDEX_STATUS, B_STRING_TYPE, 0);
|
||||
fs_create_index(volume.Device(), B_MAIL_ATTR_FLAGS, B_INT32_TYPE, 0);
|
||||
|
||||
// Start people queries
|
||||
|
||||
@@ -119,6 +119,91 @@ header_len(BFile *file)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
create_label_file(const char* label)
|
||||
{
|
||||
status_t result;
|
||||
BPath path;
|
||||
|
||||
find_directory(B_USER_SETTINGS_DIRECTORY, &path, true);
|
||||
path.Append("Mail");
|
||||
path.Append("labels");
|
||||
if (create_directory(path.Path(), 777) != B_OK)
|
||||
return B_ERROR;
|
||||
path.Append(label);
|
||||
|
||||
BFile file(path.Path(), B_READ_WRITE | B_CREATE_FILE);
|
||||
if (file.InitCheck() != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
BString string;
|
||||
string.SetToFormat(B_MAIL_ATTR_LABEL "==\"%s\"", label);
|
||||
file.WriteAttrString("_trk/qrystr", &string);
|
||||
string = "E-mail";
|
||||
file.WriteAttrString("_trk/qryinitmime", &string);
|
||||
result = BNodeInfo(&file).SetType("application/x-vnd.Be-query");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
add_folder_menu_items(BMenu* menu, const char* folder, uint32 what)
|
||||
{
|
||||
BPath path;
|
||||
BPath label_path;
|
||||
BDirectory directory;
|
||||
BEntry entry;
|
||||
|
||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path, true) != B_OK)
|
||||
return B_ERROR;
|
||||
path.Append("Mail");
|
||||
path.Append(folder);
|
||||
directory.SetTo(path.Path());
|
||||
if (directory.InitCheck() != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
// skip existing menu items
|
||||
int32 index = menu->CountItems();
|
||||
int32 skipItems = index;
|
||||
while (directory.GetNextEntry(&entry, true) == B_OK) {
|
||||
if (entry.InitCheck() != B_OK)
|
||||
break;
|
||||
|
||||
entry.GetPath(&label_path);
|
||||
const char* label = label_path.Leaf();
|
||||
|
||||
// Make sure the label file has the correct query formula,
|
||||
// in case it wasn't created with the Mail app
|
||||
BFile file(label_path.Path(), B_READ_WRITE);
|
||||
if (file.InitCheck() != B_OK)
|
||||
continue;
|
||||
BString string;
|
||||
BString formula;
|
||||
formula.SetToFormat(B_MAIL_ATTR_LABEL "==\"%s\"", label);
|
||||
file.ReadAttrString("_trk/qrystr", &string);
|
||||
if (string != formula) {
|
||||
file.WriteAttrString("_trk/qrystr", &formula);
|
||||
string = "E-mail";
|
||||
file.WriteAttrString("_trk/qryinitmime", &string);
|
||||
BNodeInfo(&file).SetType("application/x-vnd.Be-query");
|
||||
}
|
||||
|
||||
BMessage* message = new BMessage(what);
|
||||
message->AddString("label", label);
|
||||
|
||||
if (index < 9 + skipItems)
|
||||
menu->AddItem(new BMenuItem(label, message, '1' + index - skipItems), index);
|
||||
else
|
||||
menu->AddItem(new BMenuItem(label, message), index);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
add_query_menu_items(BMenu* menu, const char* attribute, uint32 what,
|
||||
const char* format, bool popup)
|
||||
|
||||
@@ -63,6 +63,8 @@ class Words;
|
||||
|
||||
|
||||
int32 header_len(BFile*);
|
||||
status_t create_label_file(const char* label);
|
||||
int32 add_folder_menu_items(BMenu* menu, const char* folder, uint32 what);
|
||||
int32 add_query_menu_items(BMenu* menu, const char* attribute, uint32 what,
|
||||
const char* format, bool popup = false);
|
||||
|
||||
|
||||
+134
-40
@@ -88,6 +88,7 @@ of their respective holders. All rights reserved.
|
||||
#include "FieldMsg.h"
|
||||
#include "FindWindow.h"
|
||||
#include "Header.h"
|
||||
#include "LabelWindow.h"
|
||||
#include "Messages.h"
|
||||
#include "MailApp.h"
|
||||
#include "MailPopUpMenu.h"
|
||||
@@ -96,7 +97,6 @@ of their respective holders. All rights reserved.
|
||||
#include "QueryMenu.h"
|
||||
#include "Signature.h"
|
||||
#include "Settings.h"
|
||||
#include "Status.h"
|
||||
#include "String.h"
|
||||
#include "Utilities.h"
|
||||
|
||||
@@ -151,6 +151,7 @@ static const uint32 kByForumlaItem = 'Fbyq';
|
||||
// taken from src/kits/tracker/FindPanel.h
|
||||
static const int kCopyBufferSize = 64 * 1024; // 64 KB
|
||||
|
||||
static const char* kSameLabelItem = B_TRANSLATE("Same label");
|
||||
static const char* kSameRecipientItem = B_TRANSLATE("Same recipient");
|
||||
static const char* kSameSenderItem = B_TRANSLATE("Same sender");
|
||||
static const char* kSameSubjectItem = B_TRANSLATE("Same subject");
|
||||
@@ -195,8 +196,10 @@ TMailWindow::TMailWindow(BRect rect, const char* title, TMailApp* app,
|
||||
fFieldState(0),
|
||||
fPanel(NULL),
|
||||
fSaveAddrMenu(NULL),
|
||||
fLabelMenu(NULL),
|
||||
fLeaveStatusMenu(NULL),
|
||||
fEncodingMenu(NULL),
|
||||
fLabel(NULL),
|
||||
fZoom(rect),
|
||||
fEnclosuresView(NULL),
|
||||
fPrevTrackerPositionSaved(false),
|
||||
@@ -295,26 +298,7 @@ TMailWindow::TMailWindow(BRect rect, const char* title, TMailApp* app,
|
||||
AddShortcut('T', B_SHIFT_KEY | B_COMMAND_KEY,
|
||||
new BMessage(M_DELETE_NEXT));
|
||||
|
||||
subMenu->AddSeparatorItem();
|
||||
|
||||
subMenu->AddItem(new BMenuItem(B_TRANSLATE("Set to Saved"),
|
||||
new BMessage(M_CLOSE_SAVED), 'W', B_CONTROL_KEY));
|
||||
|
||||
if (add_query_menu_items(subMenu, INDEX_STATUS, M_STATUS,
|
||||
B_TRANSLATE("Set to %s")) > 0)
|
||||
subMenu->AddSeparatorItem();
|
||||
|
||||
subMenu->AddItem(new BMenuItem(B_TRANSLATE("Set to" B_UTF8_ELLIPSIS),
|
||||
new BMessage(M_CLOSE_CUSTOM)));
|
||||
|
||||
#if 0
|
||||
subMenu->AddItem(new BMenuItem(new TMenu(
|
||||
B_TRANSLATE("Set to" B_UTF8_ELLIPSIS), INDEX_STATUS, M_STATUS,
|
||||
false, false),
|
||||
new BMessage(M_CLOSE_CUSTOM)));
|
||||
#endif
|
||||
menu->AddItem(subMenu);
|
||||
|
||||
fLeaveStatusMenu = subMenu;
|
||||
} else {
|
||||
menu->AddSeparatorItem();
|
||||
@@ -322,6 +306,14 @@ TMailWindow::TMailWindow(BRect rect, const char* title, TMailApp* app,
|
||||
new BMessage(B_CLOSE_REQUESTED), 'W'));
|
||||
}
|
||||
|
||||
file.ReadAttrString(B_MAIL_ATTR_LABEL, &fLabel);
|
||||
// Add label file for current mail's label, in case it doesn't exist yet.
|
||||
if (fLabel.Length() > 0)
|
||||
create_label_file(fLabel);
|
||||
|
||||
fLabelMenu = new BMenu(B_TRANSLATE("Set label"));
|
||||
menu->AddItem(fLabelMenu);
|
||||
|
||||
menu->AddSeparatorItem();
|
||||
menu->AddItem(fPrint = new BMenuItem(
|
||||
B_TRANSLATE("Page setup" B_UTF8_ELLIPSIS),
|
||||
@@ -1061,6 +1053,47 @@ TMailWindow::MenusBeginning()
|
||||
LeaveStatus->SetLabel(label.String());
|
||||
}
|
||||
}
|
||||
|
||||
// Populate label menu
|
||||
if (fRef != NULL) {
|
||||
BFile file(fRef, B_READ_ONLY);
|
||||
BString currentLabel;
|
||||
file.ReadAttrString(B_MAIL_ATTR_LABEL, ¤tLabel);
|
||||
|
||||
BMenuItem* menuItem = new BMenuItem(B_TRANSLATE("Remove label"),
|
||||
new BMessage(M_REMOVE_LABEL));
|
||||
fLabelMenu->AddItem(menuItem);
|
||||
fLabelMenu->AddItem(new BMenuItem(B_TRANSLATE("Label as" B_UTF8_ELLIPSIS),
|
||||
new BMessage(M_NEW_LABEL)));
|
||||
|
||||
fLabelMenu->AddSeparatorItem();
|
||||
|
||||
int32 count = fLabelMenu->CountItems();
|
||||
if (add_folder_menu_items(fLabelMenu, "labels", M_SET_LABEL) > count)
|
||||
fLabelMenu->AddSeparatorItem();
|
||||
|
||||
fLabelMenu->AddItem(new BMenuItem(B_TRANSLATE("Manage labels" B_UTF8_ELLIPSIS),
|
||||
new BMessage(M_MANAGE_LABELS)));
|
||||
|
||||
if (currentLabel.Length() == 0)
|
||||
menuItem->SetEnabled(false);
|
||||
else {
|
||||
menuItem = fLabelMenu->FindItem(currentLabel);
|
||||
if (menuItem != NULL)
|
||||
menuItem->SetMarked(true);
|
||||
}
|
||||
} else
|
||||
fLabelMenu->SetEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TMailWindow::MenusEnded()
|
||||
{
|
||||
for (int32 i = fLabelMenu->CountItems(); i > 0; --i)
|
||||
delete fLabelMenu->RemoveItem(i - 1);
|
||||
|
||||
BWindow::MenusEnded();
|
||||
}
|
||||
|
||||
|
||||
@@ -1356,33 +1389,84 @@ TMailWindow::MessageReceived(BMessage* msg)
|
||||
fKeepStatusOnClose = true;
|
||||
PostMessage(B_CLOSE_REQUESTED);
|
||||
break;
|
||||
case M_CLOSE_CUSTOM:
|
||||
if (msg->HasString("status")) {
|
||||
BMessage message(B_CLOSE_REQUESTED);
|
||||
message.AddString("status", msg->GetString("status"));
|
||||
PostMessage(&message);
|
||||
} else {
|
||||
BRect r = Frame();
|
||||
BString string = "could not read";
|
||||
BNode node(fRef);
|
||||
if (node.InitCheck() == B_OK)
|
||||
node.ReadAttrString(B_MAIL_ATTR_STATUS, &string);
|
||||
|
||||
new TStatusWindow(r, this, string.String());
|
||||
case M_REMOVE_LABEL:
|
||||
{
|
||||
BNode node(fRef);
|
||||
if (node.InitCheck() == B_NO_ERROR) {
|
||||
fLabel = "";
|
||||
node.RemoveAttr(B_MAIL_ATTR_LABEL);
|
||||
|
||||
BMenuItem* item = fLabelMenu->FindMarked();
|
||||
if (item != NULL)
|
||||
item->SetMarked(false);
|
||||
|
||||
item = fLabelMenu->FindItem(B_TRANSLATE("Remove label"));
|
||||
if (item != NULL)
|
||||
item->SetEnabled(false);
|
||||
|
||||
item = fQueryMenu->FindItem(kSameLabelItem);
|
||||
if (item != NULL)
|
||||
item->SetEnabled(false);
|
||||
}
|
||||
break;
|
||||
|
||||
case M_STATUS:
|
||||
}
|
||||
case M_SET_LABEL:
|
||||
{
|
||||
const char* attribute;
|
||||
if (msg->FindString("attribute", &attribute) != B_OK)
|
||||
break;
|
||||
const char* label = msg->FindString("label");
|
||||
if (label != NULL) {
|
||||
BNode node(fRef);
|
||||
if (node.InitCheck() == B_NO_ERROR) {
|
||||
fLabel = label;
|
||||
node.RemoveAttr(B_MAIL_ATTR_LABEL);
|
||||
WriteAttrString(&node, B_MAIL_ATTR_LABEL, label);
|
||||
|
||||
BMessage message(B_CLOSE_REQUESTED);
|
||||
message.AddString("status", attribute);
|
||||
PostMessage(&message);
|
||||
BMenuItem* item = fLabelMenu->FindMarked();
|
||||
if (item != NULL)
|
||||
item->SetMarked(false);
|
||||
|
||||
item = fLabelMenu->FindItem(label);
|
||||
if (item != NULL) {
|
||||
item->SetMarked(true);
|
||||
|
||||
item = fLabelMenu->FindItem(B_TRANSLATE("Remove label"));
|
||||
if (item != NULL)
|
||||
item->SetEnabled(true);
|
||||
item = fQueryMenu->FindItem(kSameLabelItem);
|
||||
if (item != NULL)
|
||||
item->SetEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case M_MANAGE_LABELS:
|
||||
{
|
||||
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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case M_NEW_LABEL:
|
||||
new TLabelWindow(Frame(), this);
|
||||
break;
|
||||
|
||||
case M_HEADER:
|
||||
{
|
||||
bool showHeader = !fHeader->IsMarked();
|
||||
@@ -1716,6 +1800,13 @@ TMailWindow::MessageReceived(BMessage* msg)
|
||||
}
|
||||
break;
|
||||
|
||||
case M_QUERY_LABEL:
|
||||
{
|
||||
if (fLabel != "")
|
||||
_LaunchQuery(kSameLabelItem, B_MAIL_ATTR_LABEL, fLabel);
|
||||
break;
|
||||
}
|
||||
|
||||
case M_QUERY_RECIPIENT:
|
||||
{
|
||||
BString searchText(fHeaderView->To());
|
||||
@@ -3120,6 +3211,9 @@ TMailWindow::_RebuildQueryMenu(bool firstTime)
|
||||
new BMessage(M_QUERY_SENDER)));
|
||||
fQueryMenu->AddItem(new BMenuItem(kSameSubjectItem,
|
||||
new BMessage(M_QUERY_SUBJECT)));
|
||||
BMenuItem* item = new BMenuItem(kSameLabelItem, new BMessage(M_QUERY_LABEL));
|
||||
fQueryMenu->AddItem(item);
|
||||
item->SetEnabled(fLabel.Length() > 0 ? true : false);
|
||||
|
||||
BPath queryPath;
|
||||
if (_GetQueryPath(&queryPath) < B_OK)
|
||||
|
||||
@@ -80,6 +80,7 @@ public:
|
||||
|
||||
virtual void FrameResized(float width, float height);
|
||||
virtual void MenusBeginning();
|
||||
virtual void MenusEnded();
|
||||
virtual void MessageReceived(BMessage*);
|
||||
virtual bool QuitRequested();
|
||||
virtual void Show();
|
||||
@@ -173,10 +174,11 @@ private:
|
||||
BMenuItem* fDeleteNext;
|
||||
BMenuItem* fSpelling;
|
||||
BMenu* fSaveAddrMenu;
|
||||
|
||||
BMenu* fLabelMenu;
|
||||
BMenu* fQueryMenu;
|
||||
BMenu* fLeaveStatusMenu;
|
||||
BMenu* fEncodingMenu;
|
||||
BString fLabel;
|
||||
|
||||
struct BitmapItem {
|
||||
BBitmap* bm;
|
||||
|
||||
@@ -88,8 +88,10 @@ enum MENUS {
|
||||
M_DELETE_NEXT,
|
||||
M_CLOSE_READ,
|
||||
M_CLOSE_SAVED,
|
||||
M_CLOSE_CUSTOM,
|
||||
M_STATUS,
|
||||
M_MANAGE_LABELS,
|
||||
M_NEW_LABEL,
|
||||
M_REMOVE_LABEL,
|
||||
M_SET_LABEL,
|
||||
M_READ_POS,
|
||||
|
||||
// edit
|
||||
@@ -110,6 +112,7 @@ enum MENUS {
|
||||
M_QUERY_RECIPIENT,
|
||||
M_QUERY_SENDER,
|
||||
M_QUERY_SUBJECT,
|
||||
M_QUERY_LABEL,
|
||||
|
||||
// encls
|
||||
M_ADD,
|
||||
|
||||
Reference in New Issue
Block a user