Reworked TrashMonitor to watch actual trash folder(s).
It was still monitoring /boot/home/Desktop/Trash folder, which don't exists anymore. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39803 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+133
-42
@@ -4,22 +4,24 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <String.h>
|
||||
#include <Alert.h>
|
||||
#include <Query.h>
|
||||
#include <VolumeRoster.h>
|
||||
#include <StringList.h>
|
||||
#include <E-mail.h>
|
||||
#include <NodeInfo.h>
|
||||
#include <Directory.h>
|
||||
#include <NodeMonitor.h>
|
||||
#include <Node.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fs_attr.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Directory.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Query.h>
|
||||
#include <E-mail.h>
|
||||
#include <Node.h>
|
||||
#include <NodeInfo.h>
|
||||
#include <NodeMonitor.h>
|
||||
#include <Path.h>
|
||||
#include <String.h>
|
||||
#include <StringList.h>
|
||||
#include <VolumeRoster.h>
|
||||
|
||||
#include <MDRLanguage.h>
|
||||
|
||||
class BMailProtocol;
|
||||
@@ -76,6 +78,7 @@ BMailProtocol::error_alert(const char *process, status_t error)
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
class DeleteHandler : public BHandler {
|
||||
public:
|
||||
DeleteHandler(BMailProtocol *a)
|
||||
@@ -96,64 +99,152 @@ class DeleteHandler : public BHandler {
|
||||
BMailProtocol *us;
|
||||
};
|
||||
|
||||
|
||||
class TrashMonitor : public BHandler {
|
||||
public:
|
||||
TrashMonitor(BMailProtocol *a, int32 chain_id)
|
||||
: us(a), trash("/boot/home/Desktop/Trash"), messages_for_us(0), id(chain_id)
|
||||
: us(a), messages_for_us(0), id(chain_id)
|
||||
{
|
||||
}
|
||||
|
||||
~TrashMonitor()
|
||||
{
|
||||
stop_watching(this);
|
||||
}
|
||||
|
||||
void MessageReceived(BMessage *msg)
|
||||
{
|
||||
if (msg->what == 'INIT') {
|
||||
node_ref to_watch;
|
||||
trash.GetNodeRef(&to_watch);
|
||||
watch_node(&to_watch,B_WATCH_DIRECTORY,this);
|
||||
BVolumeRoster volumes;
|
||||
BVolume volume;
|
||||
while (volumes.GetNextVolume(&volume) == B_OK) {
|
||||
BPath trashPath;
|
||||
if (find_directory(B_TRASH_DIRECTORY, &trashPath,
|
||||
false, &volume) == B_OK) {
|
||||
// watch this trash directory
|
||||
BNode node(trashPath.Path());
|
||||
node_ref to_watch;
|
||||
node.GetNodeRef(&to_watch);
|
||||
watch_node(&to_watch, B_WATCH_DIRECTORY, this);
|
||||
}
|
||||
}
|
||||
// Also watch for new volume
|
||||
watch_node(NULL, B_WATCH_MOUNT, this);
|
||||
return;
|
||||
}
|
||||
if ((msg->what == B_NODE_MONITOR) && (us->InitCheck() == B_OK)) {
|
||||
int32 opcode;
|
||||
if (msg->FindInt32("opcode",&opcode) < B_OK)
|
||||
|
||||
if (msg->what != B_NODE_MONITOR || (us->InitCheck() != B_OK))
|
||||
return;
|
||||
|
||||
int32 opcode;
|
||||
if (msg->FindInt32("opcode",&opcode) < B_OK)
|
||||
return;
|
||||
|
||||
if (opcode == B_DEVICE_MOUNTED) {
|
||||
dev_t device;
|
||||
if (msg->FindInt32("new device", &device) != B_OK)
|
||||
return;
|
||||
BVolume volume(device);
|
||||
BPath trashPath;
|
||||
if (find_directory(B_TRASH_DIRECTORY, &trashPath,
|
||||
false, &volume) == B_OK) {
|
||||
// watch also this new volume's trash directory
|
||||
BNode node(trashPath.Path());
|
||||
node_ref to_watch;
|
||||
node.GetNodeRef(&to_watch);
|
||||
watch_node(&to_watch, B_WATCH_DIRECTORY, this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (opcode == B_ENTRY_MOVED) {
|
||||
entry_ref entry;
|
||||
const char* name;
|
||||
msg->FindInt64("to directory", &entry.directory);
|
||||
msg->FindInt32("device", &entry.device);
|
||||
msg->FindString("name", &name);
|
||||
entry.set_name(name);
|
||||
|
||||
BNode node(&entry);
|
||||
int32 chain;
|
||||
|
||||
// check it's a mail
|
||||
if (node.ReadAttr("MAIL:chain",B_INT32_TYPE,0,&chain,sizeof(chain)) < B_OK)
|
||||
return;
|
||||
|
||||
if (opcode == B_ENTRY_MOVED) {
|
||||
int64 node(msg->FindInt64("to directory"));
|
||||
dev_t device(msg->FindInt32("device"));
|
||||
node_ref item_ref;
|
||||
item_ref.node = node;
|
||||
item_ref.device = device;
|
||||
// check it's a mail for us
|
||||
if (chain != id)
|
||||
return;
|
||||
|
||||
BDirectory moved_to(&item_ref);
|
||||
// check if it was moved to trash
|
||||
bool moved_to_trash = false;
|
||||
BPath trashPath;
|
||||
BPath entryPath(&entry);
|
||||
BVolumeRoster volumes;
|
||||
BVolume volume;
|
||||
while (volumes.GetNextVolume(&volume) == B_OK) {
|
||||
BPath trashPath;
|
||||
if (find_directory(B_TRASH_DIRECTORY, &trashPath,
|
||||
false, &volume) != B_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BNode trash_item(&moved_to,msg->FindString("name"));
|
||||
int32 chain;
|
||||
if (trash_item.ReadAttr("MAIL:chain",B_INT32_TYPE,0,&chain,sizeof(chain)) < B_OK)
|
||||
return;
|
||||
|
||||
if (chain == id)
|
||||
messages_for_us += (moved_to == trash) ? 1 : -1;
|
||||
if (strncmp(entryPath.Path(), trashPath.Path(),
|
||||
strlen(trashPath.Path())) == 0) {
|
||||
moved_to_trash = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (messages_for_us < 0)
|
||||
messages_for_us = 0; // Guard against weirdness
|
||||
|
||||
if (trash.CountEntries() == 0) {
|
||||
if (messages_for_us > 0)
|
||||
us->CheckForDeletedMessages();
|
||||
|
||||
messages_for_us += (moved_to_trash) ? 1 : -1;
|
||||
if (messages_for_us < 0) {
|
||||
// Guard against weirdness
|
||||
messages_for_us = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (opcode != B_ENTRY_REMOVED)
|
||||
return;
|
||||
|
||||
// Check if this (trash) entry removal made one trash now empty
|
||||
|
||||
bool someTrashIsEmpty = false;
|
||||
BVolumeRoster volumes;
|
||||
BVolume volume;
|
||||
while (volumes.GetNextVolume(&volume) == B_OK) {
|
||||
BPath trashPath;
|
||||
if (find_directory(B_TRASH_DIRECTORY, &trashPath,
|
||||
false, &volume) != B_OK) {
|
||||
continue;
|
||||
}
|
||||
BDirectory trash(trashPath.Path());
|
||||
if (trash.CountEntries() == 0) {
|
||||
someTrashIsEmpty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (someTrashIsEmpty) {
|
||||
// One trash is empty, check for deleted messages
|
||||
if (messages_for_us > 0)
|
||||
us->CheckForDeletedMessages();
|
||||
|
||||
messages_for_us = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
BMailProtocol *us;
|
||||
BDirectory trash;
|
||||
int32 messages_for_us;
|
||||
int32 id;
|
||||
};
|
||||
|
||||
} // unnamed namspace
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
// #pragma mark BMailProtocol
|
||||
|
||||
|
||||
BMailProtocol::BMailProtocol(BMessage *settings, BMailChainRunner *run)
|
||||
: BMailFilter(settings),
|
||||
@@ -173,7 +264,7 @@ BMailProtocol::BMailProtocol(BMessage *settings, BMailChainRunner *run)
|
||||
if (node.InitCheck() >= B_OK) {
|
||||
// We already have a directory so we can try to read metadata
|
||||
// from it. Note that it is normal for this directory not to
|
||||
// be founf on the first run as it will be later created by
|
||||
// be found on the first run as it will be later created by
|
||||
// the INBOX system filter.
|
||||
attr_info info;
|
||||
if (node.GetAttrInfo(attr_name.String(),&info) < B_OK) {
|
||||
|
||||
Reference in New Issue
Block a user