void BTrashWatcher::MessageReceived(BMessage* message) { if (message->what != B_NODE_MONITOR) { _inherited::MessageReceived(message); return; } switch (message->FindInt32("opcode")) { case B_ENTRY_CREATED: if (!fTrashFull) { fTrashFull = true; UpdateTrashIcons(); } break; case B_ENTRY_MOVED: { // allow code to fall through if move is from/to trash // but do nothing for moves in the same directory ino_t toDir; ino_t fromDir; message->FindInt64("from directory", &fromDir); message->FindInt64("to directory", &toDir); if (fromDir == toDir) break; } // fall thru case B_DEVICE_UNMOUNTED: // fall thru case B_ENTRY_REMOVED: { bool full = CheckTrashDirs(); if (fTrashFull != full) { fTrashFull = full; UpdateTrashIcons(); } break; } // We should handle DEVICE_UNMOUNTED here too to remove trash case B_DEVICE_MOUNTED: { dev_t device; BDirectory trashDir; if (message->FindInt32("new device", &device) == B_OK && FSGetTrashDir(&trashDir, device) == B_OK) { node_ref trashNode; trashDir.GetNodeRef(&trashNode); TTracker::WatchNode(&trashNode, B_WATCH_DIRECTORY, this); fTrashNodeList.AddItem(new node_ref(trashNode)); // Check if the new volume has anything trashed. if (CheckTrashDirs() && !fTrashFull) { fTrashFull = true; UpdateTrashIcons(); } } break; } } }
void BTrashWatcher::UpdateTrashIcons() { BVolume boot; if (BVolumeRoster().GetBootVolume(&boot) != B_OK) return; BDirectory trashDir; if (FSGetTrashDir(&trashDir, boot.Device()) == B_OK) { // pull out the icons for the current trash state from resources and // apply them onto the trash directory node size_t largeSize = 0; size_t smallSize = 0; const void *largeData = GetTrackerResources()->LoadResource('ICON', fTrashFull ? kResTrashFullIcon : kResTrashIcon, &largeSize); const void *smallData = GetTrackerResources()->LoadResource('MICN', fTrashFull ? kResTrashFullIcon : kResTrashIcon, &smallSize); if (largeData) trashDir.WriteAttr(kAttrLargeIcon, 'ICON', 0, largeData, largeSize); else TRESPASS(); if (smallData) trashDir.WriteAttr(kAttrMiniIcon, 'MICN', 0, smallData, smallSize); else TRESPASS(); } }
bool BNavMenu::StartBuildingItemList() { BEntry entry; if (fNavDir.device < 0 || entry.SetTo(&fNavDir) != B_OK || !entry.Exists()) return false; fItemList = new BObjectList<BMenuItem>(50); fIteratingDesktop = false; BDirectory parent; status_t status = entry.GetParent(&parent); // if ref is the root item then build list of volume root dirs fFlags = uint8((fFlags & ~kVolumesOnly) | (status == B_ENTRY_NOT_FOUND ? kVolumesOnly : 0)); if (fFlags & kVolumesOnly) return true; Model startModel(&entry, true); if (startModel.InitCheck() != B_OK || !startModel.IsContainer()) return false; if (startModel.IsQuery()) fContainer = new QueryEntryListCollection(&startModel); else if (FSIsDeskDir(&entry)) { fIteratingDesktop = true; fContainer = DesktopPoseView::InitDesktopDirentIterator(0, startModel.EntryRef()); AddRootItemsIfNeeded(); } else if (FSIsTrashDir(&entry)) { // the trash window needs to display a union of all the // trash folders from all the mounted volumes BVolumeRoster volRoster; volRoster.Rewind(); BVolume volume; fContainer = new EntryIteratorList(); while (volRoster.GetNextVolume(&volume) == B_OK) { if (!volume.IsPersistent()) continue; BDirectory trashDir; if (FSGetTrashDir(&trashDir, volume.Device()) == B_OK) dynamic_cast<EntryIteratorList *>(fContainer)-> AddItem(new DirectoryEntryList(trashDir)); } } else fContainer = new DirectoryEntryList(*dynamic_cast<BDirectory *> (startModel.Node())); if (fContainer == NULL || fContainer->InitCheck() != B_OK) return false; fContainer->Rewind(); return true; }
void BTrashWatcher::UpdateTrashIcons() { BVolumeRoster roster; BVolume volume; roster.Rewind(); BDirectory trashDir; while (roster.GetNextVolume(&volume) == B_OK) { if (FSGetTrashDir(&trashDir, volume.Device()) == B_OK) { // pull out the icons for the current trash state from resources // and apply them onto the trash directory node size_t largeSize = 0; size_t smallSize = 0; const void* largeData = GetTrackerResources()->LoadResource('ICON', fTrashFull ? R_TrashFullIcon : R_TrashIcon, &largeSize); const void* smallData = GetTrackerResources()->LoadResource('MICN', fTrashFull ? R_TrashFullIcon : R_TrashIcon, &smallSize); #ifdef HAIKU_TARGET_PLATFORM_HAIKU size_t vectorSize = 0; const void* vectorData = GetTrackerResources()->LoadResource( B_VECTOR_ICON_TYPE, fTrashFull ? R_TrashFullIcon : R_TrashIcon, &vectorSize); if (vectorData) { trashDir.WriteAttr(kAttrIcon, B_VECTOR_ICON_TYPE, 0, vectorData, vectorSize); } else TRESPASS(); #endif if (largeData) { trashDir.WriteAttr(kAttrLargeIcon, 'ICON', 0, largeData, largeSize); } else TRESPASS(); if (smallData) { trashDir.WriteAttr(kAttrMiniIcon, 'MICN', 0, smallData, smallSize); } else TRESPASS(); } } }
void BTrashWatcher::WatchTrashDirs() { BVolumeRoster volRoster; volRoster.Rewind(); BVolume volume; while (volRoster.GetNextVolume(&volume) == B_OK) { if (volume.IsReadOnly() || !volume.IsPersistent()) continue; BDirectory trashDir; if (FSGetTrashDir(&trashDir, volume.Device()) == B_OK) { node_ref trash_node; trashDir.GetNodeRef(&trash_node); watch_node(&trash_node, B_WATCH_DIRECTORY, this); fTrashNodeList.AddItem(new node_ref(trash_node)); } } }
bool BTrashWatcher::CheckTrashDirs() { BVolumeRoster volRoster; volRoster.Rewind(); BVolume volume; while (volRoster.GetNextVolume(&volume) == B_OK) { if (volume.IsReadOnly() || !volume.IsPersistent()) continue; BDirectory trashDir; FSGetTrashDir(&trashDir, volume.Device()); trashDir.Rewind(); BEntry entry; if (trashDir.GetNextEntry(&entry) == B_OK) return true; } return false; }